1. 程式人生 > 實用技巧 >Problem About Weighted Sum

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