Problem About Weighted Sum

题目链接:https://codeforces.ml/edu/course/2/lesson/5/4/practice/contest/280801/problem/D

思路:维护 ans 和sum 两个值   ans为当前区间段的答案,sum为当前区间和

那么每次查询的时候即是 用当前区间的答案加上当前区间的和乘上参数, 传递参数 代表后面的数要乘上多少倍

假设 两段区间  1 2 3 4 5   一段区间是1~3 那么4~5的时候 4~5的ans还要乘上前面的3倍 从 1*a4+2*a5 再变成1*a4+2*a5+ 3*(a4+a5)

参数h 即是要乘的倍数 q代表前面有多少个数

  1 #include<bits/stdc++.h>
  2 #define ll long long
  3 #define pb push_back
  4 using namespace std;
  5 const int maxn=1e5+10;
  6 const int mod=1e9+7;
  7 int a[maxn];
  8 
  9 int n,m;
 10 
 11 struct ac
 12 {
 13     int l,r;
 14     ll ans,sum;
 15     ll lazy;
 16     void update(ll v)
 17     {
 18         ll len=r-l+1;
 19         lazy+=v;
 20         sum+=v*len;
 21         ans+=len*(len+1)/2*v;
 22     }
 23 };
 24 ac tree[maxn*4];
 25 
 26 void pushup(int x)
 27 {
 28     tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;
 29     int len=tree[x<<1].r-tree[x<<1].l+1;
 30     tree[x].ans=tree[x<<1].ans+tree[x<<1|1].ans+tree[x<<1|1].sum*len;
 31 }
 32 void pushdown(int x)
 33 {
 34     int v=tree[x].lazy;
 35     if(v)
 36     {
 37         tree[x<<1].update(v);
 38         tree[x<<1|1].update(v);
 39         tree[x].lazy=0;
 40     }
 41 }
 42 
 43 void build(int x,int l,int r)
 44 {
 45     tree[x].l=l,tree[x].r=r;
 46     if(l==r)
 47     {
 48         tree[x].ans=tree[x].sum=a[l];
 49     }
 50     else
 51     {
 52         int mid=(l+r)/2;
 53         build(x<<1,l,mid);
 54         build(x<<1|1,mid+1,r);
 55         pushup(x);
 56     }
 57 }
 58 
 59 void update(int x,int l,int r,int v)
 60 {
 61     int L=tree[x].l,R=tree[x].r;
 62     if(l<=L&&R<=r)
 63     {
 64         tree[x].update(v);
 65     }
 66     else
 67     {
 68         pushdown(x);
 69         int mid=(L+R)/2;
 70         if(l<=mid) update(x<<1,l,r,v);
 71         if(r>mid) update(x<<1|1,l,r,v);
 72         pushup(x);
 73     }
 74 }
 75 
 76 ll query(int x,int l,int r,int h,int q)
 77 {
 78     int L=tree[x].l,R=tree[x].r;
 79     if(L>r||R<l)
 80         return 0;
 81     if(l<=L&&R<=r)
 82     {
 83         return tree[x].ans+1ll*h*tree[x].sum;
 84     }
 85     else
 86     {
 87         pushdown(x);
 88         int mid=(L+R)/2;
 89         if(l<=mid) return query(x<<1,l,r,h,q)+query(x<<1|1,l,r,mid-q+1+h,mid+1);
 90         else return query(x<<1|1,l,r,h,q);
 91     }
 92 }
 93 
 94 
 95 
 96 int main()
 97 {
 98     ios::sync_with_stdio(0);
 99     cin.tie(0);
100     cin>>n>>m;
101     for(int i=1;i<=n;i++)
102     {
103         cin>>a[i];
104     }
105     build(1,1,n);
106     for(int i=0;i<m;i++)
107     {
108         int x,l,r,d;
109         cin>>x>>l>>r;
110         if(x==1)
111         {
112             cin>>d;
113             update(1,l,r,d);
114         }
115         else
116         {
117             cout<<query(1,l,r,0,l)<<'\n';
118         }
119     }
120 
121 
122 
123 
124 
125 }
View Code

 

posted @ 2020-12-28 22:20  canwinfor  阅读(157)  评论(0)    收藏  举报