标签:soft class border stdout ott mil base man turn
稍微复杂一点的分块
和数列分块1相比,多的只是区间查询
!!!别看只有2个字的差别,两道题差多了!!!
首先,因为是区间查询,所以每个区间还应该维护一个和
同时在添加时,非完整区间的标记要下放(暴力跑一下)
查询时输出完整区间的和和不完整区间每个元素的和即可
ok
#include<iostream> #include<cstdio> #include<cmath> using namespace std; long long x[50005],sy[50005],bj[10005],sum[10005],n,c,opt,l,r,cd; void pushdown(int wz) { for(register int ltt=(wz-1)*cd+1;ltt<=wz*cd;ltt++) { x[ltt]+=bj[wz]; } bj[wz]=0; } void add(int zuo,int you,int v) { int k=sy[zuo]; int j=sy[you]; if(k==j) { pushdown(k); for(register int ltt=zuo;ltt<=you;ltt++) { x[ltt]+=v; sum[k]+=v; } return; } for(register int ltt=k+1;ltt<=j-1;ltt++) { bj[ltt]+=v; sum[ltt]+=v*cd; } pushdown(k); pushdown(j); for(register int ltt=zuo;ltt<=k*cd;ltt++) { x[ltt]+=v; sum[sy[ltt]]+=v; } for(register int ltt=(j-1)*cd+1;ltt<=you;ltt++) { x[ltt]+=v; sum[sy[ltt]]+=v; } } long long query(int zuo,int you,int mod) { long long ans=0; int k=sy[zuo]; int j=sy[you]; if(k==j) { // pushdown(k); for(register int ltt=zuo;ltt<=you;ltt++) { ans+=x[ltt]+bj[k]; } ans=ans%(mod+1); return ans; } for(register int kkk=k+1;kkk<=j-1;kkk++) { ans+=sum[kkk]; } for(register int ltt=zuo;ltt<=k*cd;ltt++) { ans+=x[ltt]+bj[k]; } for(register int ltt=(j-1)*cd+1;ltt<=you;ltt++) { ans+=x[ltt]+bj[j]; } ans=ans%(mod+1); return ans; } int main() { // freopen("a1.in","r",stdin); // freopen("1.out","w",stdout); scanf("%d",&n); cd=sqrt(n); int cnt=1; int bnt=0; for(register int i=1;i<=n;i++) { scanf("%d",&x[i]); bnt++; sy[i]=cnt; sum[cnt]+=x[i]; if(bnt==cd) { bnt=0; cnt++; } } for(register int i=1;i<=n;i++) { scanf("%d%d%d%d",&opt,&l,&r,&c); if(opt==0) { add(l,r,c); } else { printf("%d\n",query(l,r,c)); } } // system("fc 1.out a1.out"); // system("pause"); }
标签:soft class border stdout ott mil base man turn
原文地址:https://www.cnblogs.com/ztz11/p/8973202.html