洛谷 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 }
View Code

 

posted @ 2018-01-04 20:32  Driver_Lao  阅读(173)  评论(0编辑  收藏  举报