Codeforces 1053C Putting Boxes Together 树状数组
原文链接https://www.cnblogs.com/zhouzhendong/p/CF1053C.html
题目传送门 - CF1053C
题意
有 $n$ 个物品,第 $i$ 个物品在位置 $a_i$ ,重量为 $w_i$ 。使得重量为 $x$ 的物品移动一单位距离的花费是 $x$ 。接下来 $q$ 个操作,有两种类型:
1. 将物品 $i$ 的重量修改成 $nw$ 。
2. 询问把区间 $[L,R]$ 内的物品都移动到一段连续的区间 $[x,x+R-L]$ 内,并且互不重叠,相对顺序保持不变,问最小花费。
保证 $a_i$ 递增。
$n,q\leq 2\times 10^5, 1\leq a_i,w_i\leq 10^9$
题解
比赛的时候,很快想到了解决这个问题的前几步:
$a[i]-=i$
然后就变成了所有物品都移动到一个点的问题了。直接求带权中位数就好了。
然后我“成功”地把问题转化成了下面这个问题:
"求区间带权中位数,单点修改。"
哎呀这个区间中位数还得树套树啊,得统计区间小于等于某一个数的答案还得单点修改啊!
于是我花了20分钟想出了一个非常复杂的树套树 log^2 做法。于是码呀码,码到最后15分钟码完了,根本调不出来。
赛后膜了一发 App ,我仍然一脸懵逼。
直到最后躺在床上的时候,突然我明白了。
我忽略了什么呢?
位置是单调不减的!!!
所以要什么树套树啊。
言归正传。
考虑求区间中位数。直接二分就好了,用树状数组快速计算区间权值和。
考虑得到的位置为 $p$ ,那么,$ans=\sum_{i\in[L,R]} w_i|a_i-p|$ ,再用个树状数组维护一下区间 $w_ia_i$ 的和,最后求答案的时候分两段算就好了。
我***************连这种玩意儿都没做出来,我好菜啊……
说着就伤心,我也知道这个题解质量不好,但是我很伤心,就不改了吧。
时间复杂度 $O(n \log n + q \log^2 n)$ 。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=200005,mod=1e9+7;
LL read(){
LL x=0,f=1;
char ch=getchar();
while (!isdigit(ch)&&ch!='-')
ch=getchar();
if (ch=='-')
f=-1,ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+ch-48,ch=getchar();
return x*f;
}
int n,Q;
int a[N],w[N];
LL c1[N];
int c2[N];
void add(int &x,int y){if ((x+=y)>=mod)x-=mod;}
void add1(int x,LL d){for (;x<=n;x+=x&-x)c1[x]+=d;}
void add2(int x,int d){for (;x<=n;x+=x&-x)add(c2[x],d);}
LL ask1(int x){LL ans=0;for (;x;x-=x&-x)ans+=c1[x];return ans;}
int ask2(int x){int ans=0;for (;x;x-=x&-x)add(ans,c2[x]);return ans;}
void opt1(int i,int nw){
add1(i,-w[i]);
add2(i,(-1LL*w[i]*a[i]%mod+mod)%mod);
w[i]=nw;
add1(i,w[i]);
add2(i,1LL*w[i]*a[i]%mod);
}
void opt2(int L,int R){
LL t=ask1(L-1);
LL sum=ask1(R)-t;
int le=L,ri=R,mid,ans=R;
while (le<=ri){
mid=(le+ri)>>1;
LL v=ask1(mid)-t;
if (v*2>=sum)
ri=mid-1,ans=mid;
else
le=mid+1;
}
LL v11=ask2(ans)-ask2(L-1),v12=-1LL*a[ans]*((ask1(ans)-t)%mod)%mod;
LL v21=ask2(R)-ask2(ans),v22=-1LL*a[ans]*((ask1(R)-ask1(ans))%mod)%mod;
LL Ans=(v21+v22-v11-v12)%mod;
Ans=(Ans+mod)%mod;
printf("%I64d\n",Ans);
}
int main(){
n=read(),Q=read();
for (int i=1;i<=n;i++)
a[i]=read()-i+n;
memset(c1,0,sizeof c1);
memset(c2,0,sizeof c2);
for (int i=1;i<=n;i++){
w[i]=read();
add1(i,w[i]);
add2(i,1LL*w[i]*a[i]%mod);
}
while (Q--){
int x=read(),y=read();
if (x<0)
opt1(-x,y);
else
opt2(x,y);
}
return 0;
}
Codeforces 1053C Putting Boxes Together 树状数组的更多相关文章
- CodeForces 1058 F Putting Boxes Together 树状数组,带权中位数
Putting Boxes Together 题意: 现在有n个物品,第i个物品他的位置在a[i],他的重量为w[i].每一个物品移动一步的代价为他的w[i].目前有2种操作: 1. x y 将第x的 ...
- codeforces 985 E. Pencils and Boxes (dp 树状数组)
E. Pencils and Boxes time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- [Codeforces 1053C] Putting Boxes Together
Link: Codeforces 1053C 传送门 Solution: 先推出一个结论: 最后必有一个点不动且其为权值上最中间的一个点 证明用反证证出如果不在中间的点必有一段能用代价少的替代多的 这 ...
- CodeForces 828E DNA Evolution(树状数组)题解
题意:给你一个串k,进行两个操作: “1 a b”:把a位置的字母换成b “2 l r s”:求l到r有多少个字母和s匹配,匹配的条件是这样:从l开始无限循环s形成一个串ss,然后匹配ss和指定区间的 ...
- Codeforces 909C Python Indentation:树状数组优化dp
题目链接:http://codeforces.com/contest/909/problem/C 题意: Python是没有大括号来标明语句块的,而是用严格的缩进来体现. 现在有一种简化版的Pytho ...
- CodeForces - 597C Subsequences 【DP + 树状数组】
题目链接 http://codeforces.com/problemset/problem/597/C 题意 给出一个n 一个 k 求 n 个数中 长度为k的上升子序列 有多少个 思路 刚开始就是想用 ...
- Codeforces 635D Factory Repairs【树状数组】
又是看了很久的题目... 题目链接: http://codeforces.com/contest/635/problem/D 题意: 一家工厂生产维修之前每天生产b个,维修了k天之后每天生产a个,维修 ...
- codeforces 570 D. Tree Requests 树状数组+dfs搜索序
链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds mem ...
- codeforces E. DNA Evolution(树状数组)
题目链接:http://codeforces.com/contest/828/problem/E 题解:就是开4个数组举一个例子. A[mod][res][i]表示到i位置膜mod余数是res的‘A’ ...
随机推荐
- 1.ROS启动小乌龟
启动turtlesim 在三个不同的终端中分别执行如下三个指令 roscore rosrun turtlesim turtlesim_node rosrun turtlesim turtle_ ...
- CF 2B The least round way DP+Math
题意: 找出一条路, 使每个节点相乘,得到的数末尾 0 最少 每次移动只能向右或者向下, 找到后打印路径 ///按照题目要求,就是找出一条从左上角到右下角中每个数含2 or 5 最少的路 ///可以用 ...
- Jmeter之响应结果乱码解决
场景: 在测试过程中,我们可能需要查看结果树,但是发现里面的响应数据在“Document”以外的其他表现形式下都有乱码,如下图就是设置了以Text的形式展示,响应数据包含乱码: 分析:原因是Jmete ...
- pip的常用命令
前言 pip作为Python的御用包管理工具有着强大的功能,但是许多命令需要我们使用的时候借助搜索引擎查找(尤其是我), 于是我想将我使用到的命令整合下来,以后不用麻烦去找了,也希望能给你带来帮助.文 ...
- 39)django-XSS 过滤
使用kingedit别人是可以输入script代码.这在后台是不允许script代码运行的. 这里主要使用beatifulSoup过滤 示例1 beatufulsoup4 from bs4 impor ...
- Android性能优化之图片压缩优化
1 分类Android图片压缩结合多种压缩方式,常用的有尺寸压缩.质量压缩.采样率压缩以及通过JNI调用libjpeg库来进行压缩. 参考此方法:Android-BitherCompress 备注:对 ...
- PID控制器开发笔记之五:变积分PID控制器的实现
在普通的PID控制算法中,由于积分系数Ki是常数,所以在整个控制过程中,积分增量是不变的.然而,系统对于积分项的要求是,系统偏差大时,积分作用应该减弱甚至是全无,而在偏差小时,则应该加强.积分系数取大 ...
- Confluence 6 任务的类型
下面是有关你可以调整的计划任务列表. Confluence 备份(Back Up Confluence) 对 Confluence 站点执行备份操作. 每集群(Per cluster) At 2am ...
- Confluence 6 导入一个 Confluence 站点
有下面 2 种类方法可以导入一个站点 - 通过上传一个文件或者从你 Confluence 服务器上读取一个目录.上传文件仅仅是针对一个小站点的情况.为了取得最好的导入结果,我们推荐你从服务器上的目录上 ...
- (不断更新)关于显著性检测的调研-Salient Object Detection: A Survey
<Salient Object Detection: A Survey>作者:Ali Borji.Ming-Ming Cheng.Huaizu Jiang and Jia Li 基本按照文 ...