Link:

Codeforces 1053C 传送门

Solution:

先推出一个结论:

最后必有一个点不动且其为权值上最中间的一个点

证明用反证证出如果不在中间的点必有一段能用代价少的替代多的

这样问题转换为求出区间第一个大于权值和一半的点,并求结果

如果只考虑半边的结果为$\sum_{i=1}^{mid} (pos[mid]-pos[i]-(mid-i))*w[i]$

将$pos[i]$修改为$pos[i]-i$之后维护$\sum pos[i]*w[i]$的和即可

以上操作可以用两颗线段树来维护

注意:

1、维护$w[i]$时不能取模!

2、对于求权值中间点可以二分+树状数组也可以直接在线段树上二分

线段树上二分时注意如果已经在区间内查询值要不断更新

Code:

#include <bits/stdc++.h>

using namespace std;
#define X first
#define Y second
#define pb push_back
#define mid ((l+r)>>1)
#define lc k<<1,l,mid
#define rc k<<1|1,mid+1,r
typedef double db;
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=5e5+,INF=<<,MOD=1e9+; struct SGT
{
ll seg[MAXN<<];
//分清何时要取模
void Update(int a,ll x,int f,int k,int l,int r)
{
if(l==r)
{seg[k]+=x;if(f) seg[k]%=MOD;return;}
if(a<=mid) Update(a,x,f,lc);
else Update(a,x,f,rc);
seg[k]=seg[k<<]+seg[k<<|];
if(f) seg[k]%=MOD;
}
ll Query(int a,int b,int f,int k,int l,int r)
{
if(a<=l&&r<=b) return seg[k];
ll ret=;
if(a<=mid) ret+=Query(a,b,f,lc);
if(b>mid) ret+=Query(a,b,f,rc);
return f?ret%MOD:ret;
}
//注意线段树二分的处理及此处的引用
int Find(int a,int b,ll &x,int k,int l,int r)
{
if(a<=l&&r<=b)
{
if(seg[k]<x){x-=seg[k];return INF;}
if(l==r) return l;
if(x<=seg[k<<]) return Find(a,b,x,lc);
else{x-=seg[k<<];return Find(a,b,x,rc);}
}
int ret=INF;
if(a<=mid)
ret=min(ret,Find(a,b,x,lc));
if(b>mid&&ret==INF)
ret=min(ret,Find(a,b,x,rc));
return ret;
}
}sw,sm;
int n,q,x,y,pos[MAXN],w[MAXN]; int main()
{
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
scanf("%d",&pos[i]),pos[i]-=i;
for(int i=;i<=n;i++)
{
scanf("%d",&w[i]);
sw.Update(i,w[i],,,,n);
sm.Update(i,1ll*w[i]*pos[i],,,,n);
} while(q--)
{
scanf("%d%d",&x,&y);
if(x<)
{
x=-x;
sw.Update(x,-w[x],,,,n);
sm.Update(x,-1ll*w[x]*pos[x],,,,n);
w[x]=y;
sw.Update(x,w[x],,,,n);
sm.Update(x,1ll*w[x]*pos[x],,,,n);
}
else
{
//此时不能取模
ll sum=(sw.Query(x,y,,,,n)+)/;
int p=sw.Find(x,y,sum,,,n);
ll t1=(sw.Query(x,p,,,,n)*pos[p]%MOD-sm.Query(x,p,,,,n)+MOD)%MOD;
ll t2=(-sw.Query(p+,y,,,,n)*pos[p]%MOD+sm.Query(p+,y,,,,n)+MOD)%MOD;
printf("%lld\n",(t1+t2)%MOD);
}
}
return ;
}

[Codeforces 1053C] Putting Boxes Together的更多相关文章

  1. Codeforces 1053C Putting Boxes Together 树状数组

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF1053C.html 题目传送门 - CF1053C 题意 有 $n$ 个物品,第 $i$ 个物品在位置 $a ...

  2. 2018.09.24 codeforces 1053C. Putting Boxes Together(线段树)

    传送门 就是让你维护动态的区间带权中位数. 然而昨晚比赛时并没有调出来. 想找到带权中位数的中点可以二分(也可以直接在线段树上找). 也就是二分出第一个断点,使得断点左边的和恰好大于或等于断点右边的和 ...

  3. Codeforces 1053 C - Putting Boxes Together

    C - Putting Boxes Together 思路: 求带权中位数 用树状数组维护修改 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) ...

  4. CodeForces 1058 F Putting Boxes Together 树状数组,带权中位数

    Putting Boxes Together 题意: 现在有n个物品,第i个物品他的位置在a[i],他的重量为w[i].每一个物品移动一步的代价为他的w[i].目前有2种操作: 1. x y 将第x的 ...

  5. Putting Boxes Together CodeForces - 1030F (带权中位数)

    #include <iostream> #include <algorithm> #include <cstdio> #include <math.h> ...

  6. Codeforces 488B - Candy Boxes

    B. Candy Boxes 题目链接:http://codeforces.com/problemset/problem/488/B time limit per test 1 second memo ...

  7. Educational Codeforces Round 31- D. Boxes And Balls

    D. Boxes And Balls time limit per test2 seconds memory limit per test256 megabytes 题目链接:http://codef ...

  8. [CF1053C]Putting Boxes Together(线段树)

    http://codeforces.com/blog/entry/62013 两个结论: 1.一定有一个箱子不用动. 2.不动的箱子一定是加权前缀和为S/2的那个. 1显然,2由1易得. 于是问题变为 ...

  9. CF1030F Putting Boxes Together

    昨晚的比赛题.(像我这种蒟蒻只能打打div2) 题意 给你$n$个物品,每一个物品$i$,有一个权值$w_i$和一个位置$a_i$,定义移动一个物品$i$到位置$t$的代价为$w_i * \left ...

随机推荐

  1. UIImagePickerController---iOS-Apple苹果官方文档翻译

    //本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址  //转载请注明出处--本文永久链接:http://www.cnblogs.com ...

  2. LESS使用简介!

    我真的真的极度痛苦. 原本用了那么久的LESS,一直都是用编译工具(考拉)进行编译的,今天试了试用less.js来搞,按官网的都一毛一样,然而!就是编译不出来! 我用来擦鼻涕的卫生纸都一下午用了大半卷 ...

  3. Centos 7 安装jdk1.7

    在linux中安装jdk是很平凡的事情了,刚学习linux给自己留下一笔记.刚安装centos其中可以会附带jdk,但是这并不影响,只要下载自己的jdk然后替换相对应的环境变量即可. 1.下载相对应的 ...

  4. Part2-HttpClient官方教程-Chapter4-HTTP 认证

    原文链接地址 HttpClient 提供对由 HTTP 标准规范定义的认证模式的完全支持.HttpClient 的认证框架可以扩展支持非标准的认证模式,比如 NTLM 和 SPNEGO. 4.1 用户 ...

  5. 工具===代替cmd的conemu设置

    conemu设置 Win+Alt+P进入设置界面,字体设置: 隐藏右上角菜单和窗口标题. (Ctrl + ~ 隐藏/显示terminal) 设置背景图片 避免误操作,关闭/新建确认 设置win+w默认 ...

  6. hardseed

    hardseed https://github.com/yangyangwithgnu/hardseed

  7. Oracle 内存管理

    --内存分配建库时可以先分配系统内存的50%-80%给Oracle,后期根据业务再进行调整.SGA.PGA分配比例:OLTP:SGA %80 , PGA %20OLAP:SGA %50 , PGA % ...

  8. mongodb实现批量修改数据

    var rds = db.REGIPATIENTREC.find({mzh:{$lt:"0"},usrOrg:"石景山中西医结合医院"}); var show ...

  9. 获取分组后的TOP 1和TOP N记录

    MySQL获取分组后的TOP 1和TOP N记录 有时会碰到一些需求,查询分组后的最大值,最小值所在的整行记录或者分组后的top n行的记录,在一些别的数据库可能有窗口函数可以方面的查出来,但是MyS ...

  10. 设置Eclipse/MyEclipse中编辑界面点击任何文件后Package Explorer导航自动定位该文件

    原文:http://www.myexception.cn/eclipse/425836.html 设置步骤: 导航Package Explorer的右上角有一个黄色双向箭头图标,鼠标移动到上面提示“L ...