A Simple Problem with Integers Lazy标记版线段树(区间修改)
 链接:https://ac.nowcoder.com/acm/problem/50454
来源:牛客网
题目描述
给定数列a[1],a[2],…,a[n]a[1],a[2], \dots,a[n]a[1],a[2],…,a[n],你需要依次进行q个操作,操作有两类:
  1 l r x:给定l,r,x,对于所有i∈[l,r]i \in[l,r]i∈[l,r],将a[i]加上x(换言之,将a[l],a[l+1],…,a[r]a[l],a[l+1], \dots,a[r]a[l],a[l+1],…,a[r]分别加上x); 
  2 l r:给定l,r,求∑i=lra[i]\sum_{i=l}^ra[i]∑i=lra[i]的值(换言之,求a[l]+a[l+1]+⋯+a[r]a[l]+a[l+1]+ \dots+a[r]a[l]+a[l+1]+⋯+a[r]的值)。 
输入描述:
第一行包含2个正整数n,q,表示数列长度和询问个数。保证1≤n,q≤1061 \le n,q \le10^61≤n,q≤106。
第二行n个整数a[1],a[2],…,a[n]a[1],a[2], \dots,a[n]a[1],a[2],…,a[n],表示初始数列。保证∣a[i]∣≤106|a[i]| \le10^6∣a[i]∣≤106。
接下来q行,每行一个操作,为以下两种之一:
1 l r x:对于所有i∈[l,r]i \in[l,r]i∈[l,r],将a[i]加上x;
2 l r:输出∑i=lra[i]\sum_{i=l}^ra[i]∑i=lra[i]的值。保证1≤l≤r≤n,1 \le l \le r \le n,1≤l≤r≤n,∣x∣≤106|x| \le10^6∣x∣≤106。
输出描述:
对于每个2lr操作,输出一行,每行有一个整数,表示所求的结果。
示例1
备注:
对于所有数据,1≤n,q≤106,1 \le n,q \le10^6,1≤n,q≤106,∣a[i]∣≤106|a[i]| \le10^6∣a[i]∣≤106,1≤l≤r≤n,1 \le l \le r \le n,1≤l≤r≤n,∣x∣≤106|x| \le10^6∣x∣≤106。
分析
线段树带lazy标记,就像账单,如果没有必要,一堆人一起加分,要看某个人的分数的时候,再把这个一堆人的加分细分给各个人。
//-------------------------代码---------------------------- #define int ll const int N = 1e6+10; int n,m,q; int a[N]; struct node { int l,r,sum,lazy; }tr[N * 4]; void build(int p,int l,int r) { if(l == r) { tr[p] = {l,l,a[l],0}; rt; } int mid = l + r >> 1; build(p << 1,l,mid); build(p<<1|1,mid + 1,r); tr[p] = {l,r,tr[p<<1].sum + tr[p<<1|1].sum,0}; } void push_down(int p,int tot) { tr[p<<1|1].lazy += tr[p].lazy; tr[p<<1].lazy += tr[p].lazy; tr[p<<1].sum += (tot - tot / 2) * tr[p].lazy; tr[p<<1|1].sum += (tot / 2) * tr[p].lazy; tr[p].lazy = 0; } void add(int p,int l,int r,int x) { if(l <= tr[p].l && tr[p].r <= r) { tr[p].lazy += x; tr[p].sum += x * (tr[p].r - tr[p].l + 1) ; rt; } if(tr[p].lazy) { push_down(p,tr[p].r-tr[p].l+1); } int mid = tr[p].l + tr[p].r >> 1; if(l <= mid) add(p << 1,l,r,x); if(r > mid) add(p << 1 | 1,l,r,x); tr[p].sum = tr[p << 1].sum + tr[p<<1|1].sum; } // ll query(int p, int l, int r, int nl, int nr){ // add(1, 1, n, l, r, x); int query(int p,int l,int r) { if(l <= tr[p].l && tr[p].r <= r) { return tr[p].sum; } if(tr[p].lazy) { push_down(p,tr[p].r - tr[p].l + 1); } int mid = tr[p].l + tr[p].r >>1; int sum = 0; if( l <= mid) sum += query(p << 1, l,r); if(r > mid) sum += query(p<<1|1, l ,r) ; return sum; } void solve() { // cin>>n>>m; cin>>n>>q; fo(i,1,n) cin>>a[i]; build(1,1,n); fo(i,1,q) { int op;cin>>op; if(op == 1) { int l,r,x;cin>>l>>r>>x; add(1,l,r,x); } else { int l,r;cin>>l>>r; cout<<query(1,l,r)<<endl; // bd;gg; } } // fo(i,1,2*n) { // cout<<tr[i].sum<<' '; // }cout<<endl; } void main_init() {} signed main(){ AC();clapping();TLE; cout<<fixed<<setprecision(12); main_init(); // while(cin>>n,n) // while(cin>>n>>m,n,m) // int t;cin>>t;while(t -- ) solve(); // {solve(); } return 0; } /*样例区 */ //------------------------------------------------------------
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号