Codeforces Round #250 Div1D 438D The Child and Sequence 线段树+势能分析

来源:互联网 发布:重庆房地产楼盘数据库 编辑:程序博客网 时间:2024/04/29 10:30

这道题刚开始一看,涉及到序列上区间的维护问题,感觉是线段树。但是仔细想了想又觉得线段树做会TLE,然后我就看了一下别人的代码,发现就是很普通的一个思路。

我们不仅要用线段树维护序列上的和,还要维护一个最大值。每次向下更新时,如果发现这一段的最大值小于那个模,就不再向下修改。一切看上去都很暴力,为什么能AC这个题呢?

任何数在mod k操作的时候,要么不变,要么会变成比原来小一半的数。这样,我们给每个数一个势能,x的势能定义为log x,这样每次对x取模一定会减少一个势能,而每次修改增加的势能也只是log a,这样总的操作复杂度是O(n*log n*log a)。

//CF438D#include<iostream>#include<cstdio>#include<algorithm>#include<string>#include<cstring>#include<queue>#include<vector>#include<utility>using namespace std;typedef long long LL;typedef pair<long long,long long> PLL;const int MAXN=100010;int n,m,l[MAXN<<2],r[MAXN<<2],op,in1,in2,in3;LL dat[MAXN];PLL tree[MAXN<<2];PLL operator+(const PLL &a,const PLL &b){return make_pair(a.first+b.first,max(a.second,b.second));}void maketree(int x,int ll,int rr){l[x]=ll,r[x]=rr;if(ll==rr) {tree[x]=make_pair(dat[ll],dat[ll]);return;}int m=(l[x]+r[x])>>1;maketree(x<<1,ll,m);maketree(x<<1|1,m+1,rr);tree[x]=tree[x<<1]+tree[x<<1|1];}void change(int x,int pos,LL tar){if(l[x]==r[x]) {tree[x]=make_pair(tar,tar);return;}int m=(l[x]+r[x])>>1;if(pos<=m) change(x<<1,pos,tar);else change(x<<1|1,pos,tar);tree[x]=tree[x<<1]+tree[x<<1|1];}LL query(int x,int ll,int rr){if(l[x]==ll&&r[x]==rr) return tree[x].first;int m=(l[x]+r[x])>>1;if(rr<=m) return query(x<<1,ll,rr);else if(ll>m) return query(x<<1|1,ll,rr);else return query(x<<1,ll,m)+query(x<<1|1,m+1,rr);}void opmod(int x,int ll,int rr,LL tar){if(tree[x].second<tar) return;if(l[x]==r[x]) {tree[x]=make_pair(tree[x].first%tar,tree[x].first%tar);return;}int m=(l[x]+r[x])>>1;if(rr<=m) opmod(x<<1,ll,rr,tar);else if(ll>m) opmod(x<<1|1,ll,rr,tar);else {opmod(x<<1,ll,m,tar);opmod(x<<1|1,m+1,rr,tar);}tree[x]=tree[x<<1]+tree[x<<1|1];}int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) scanf("%I64d",&dat[i]);maketree(1,1,n);for(int cas=1;cas<=m;cas++){scanf("%d%d%d",&op,&in1,&in2);if(op==2) scanf("%d",&in3);if(op==1) printf("%I64d\n",query(1,in1,in2));else if(op==2) opmod(1,in1,in2,(LL)in3);else change(1,in1,(LL)in2);}return 0;}


0 0
原创粉丝点击