洛谷 1438 无聊的数列
【题解】
用线段数维护差分数组即可。
1 #include<cstdio> 2 #include<algorithm> 3 #define ls (u<<1) 4 #define rs (u<<1|1) 5 #define mid ((a[u].l+a[u].r)>>1) 6 #define len(x) (a[x].r-a[x].l+1) 7 #define LL long long 8 using namespace std; 9 const int maxn=800010; 10 struct tree{LL l,r,sum,del;}a[maxn]; 11 int opt,n,m,l,r,k,d,b[maxn]; 12 inline LL read(){ 13 int k=0,f=1; char c=getchar(); 14 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 15 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 16 return k*f; 17 } 18 void build(int u,int l,int r){ 19 a[u].l=l; a[u].r=r; 20 if(l<r) build(ls,l,mid),build(rs,mid+1,r); 21 } 22 void pushdown(int u){ 23 LL del=a[u].del; a[u].del=0; 24 a[ls].del+=del; a[rs].del+=del; 25 a[ls].sum+=len(ls)*del; a[rs].sum+=len(rs)*del; 26 } 27 void update(int u,int l,int r,LL del){ 28 if(l<=a[u].l&&a[u].r<=r){a[u].del+=del; a[u].sum+=len(u)*del; return;} 29 pushdown(u); 30 if(l<=mid) update(ls,l,r,del); 31 if(r>mid) update(rs,l,r,del); 32 a[u].sum=a[ls].sum+a[rs].sum; 33 } 34 LL query(int u,int l,int r){ 35 if(l<=a[u].l&&a[u].r<=r){return a[u].sum;} 36 pushdown(u); LL ret=0; 37 if(l<=mid) ret+=query(ls,l,r); 38 if(r>mid) ret+=query(rs,l,r); 39 return ret; 40 } 41 int main(){ 42 n=read(); m=read(); build(1,1,n+1); 43 for(int i=1;i<=n;i++) b[i]=read(); 44 for(int i=1;i<=m;i++){ 45 opt=read(); 46 if(opt==1){ 47 l=read(); r=read(); k=read(); d=read(); 48 update(1,l,l,k); 49 update(1,l+1,r,d); 50 update(1,r+1,r+1,-k-1LL*d*(r-l)); 51 } 52 else k=read(),printf("%lld\n",query(1,1,k)+b[k]); 53 //printf("QAQ "); for(int j=1;j<=n;j++) printf("%lld ",query(1,1,j)); puts(""); 54 } 55 return 0; 56 }