题目描述 Description
给你N个数,有两种操作:
1:给区间[a,b]的所有数增加X
2:询问区间[a,b]的数的和。
输入描述 Input Description
第一行一个正整数n,接下来n行n个整数,
再接下来一个正整数Q,每行表示操作的个数,
如果第一个数是1,后接3个正整数,
表示在区间[a,b]内每个数增加X,如果是2,
表示操作2询问区间[a,b]的和是多少。
pascal选手请不要使用readln读入
输出描述 Output Description
对于每个询问输出一行一个答案
样例输入 Sample Input
3
1
2
3
2
1 2 3 2
2 2 3
样例输出 Sample Output
9
数据范围及提示 Data Size & Hint
数据范围
1<=n<=200000
1<=q<=200000
思路:线段树+延迟标记
#include<iostream> #include<cstdio> #include<cmath> #include<string> #include<queue> #include<algorithm> #include<stack> #include<cstring> #include<vector> #include<list> #include<set> #include<map> #define true ture #define false flase using namespace std; #define ll long long int scan() { int res = 0 , ch ; while( !( ( ch = getchar() ) >= ‘0‘ && ch <= ‘9‘ ) ) { if( ch == EOF ) return 1 << 30 ; } res = ch - ‘0‘ ; while( ( ch = getchar() ) >= ‘0‘ && ch <= ‘9‘ ) res = res * 10 + ( ch - ‘0‘ ) ; return res ; } struct is { int l,r; ll num; int lazy; }tree[200010*3]; void build_tree(int l,int r,int pos) { tree[pos].l=l; tree[pos].r=r; tree[pos].lazy=0; if(l==r) { //tree[pos].num=1; scanf("%lld",&tree[pos].num); return; } int mid=(l+r)/2; build_tree(l,mid,pos*2); build_tree(mid+1,r,pos*2+1); tree[pos].num=tree[pos*2].num+tree[pos*2+1].num; } void update(int l,int r,int change,int pos) { if(tree[pos].l==l&&tree[pos].r==r) { tree[pos].lazy+=change; tree[pos].num+=(tree[pos].r-tree[pos].l+1)*change; return; } if(tree[pos].lazy) { tree[pos*2].num+=(tree[pos*2].r+1-tree[pos*2].l)*tree[pos].lazy; tree[pos*2+1].num+=(tree[pos*2+1].r+1-tree[pos*2+1].l)*tree[pos].lazy; tree[pos*2].lazy+=tree[pos].lazy; tree[pos*2+1].lazy+=tree[pos].lazy; tree[pos].lazy=0; } int mid=(tree[pos].l+tree[pos].r)/2; if(r<=mid) update(l,r,change,pos*2); else if(l>mid) update(l,r,change,pos*2+1); else { update(l,mid,change,pos*2); update(mid+1,r,change,pos*2+1); } tree[pos].num=tree[pos*2].num+tree[pos*2+1].num; } ll query(int l,int r,int pos) { //cout<<l<<" "<<r<<" "<<pos<<endl; if(tree[pos].l==l&&tree[pos].r==r) return tree[pos].num; if(tree[pos].lazy) { tree[pos*2].num+=(tree[pos*2].r+1-tree[pos*2].l)*tree[pos].lazy; tree[pos*2+1].num+=(tree[pos*2+1].r+1-tree[pos*2+1].l)*tree[pos].lazy; tree[pos*2].lazy+=tree[pos].lazy; tree[pos*2+1].lazy+=tree[pos].lazy; tree[pos].lazy=0; } int mid=(tree[pos].l+tree[pos].r)/2; if(l>mid) return query(l,r,pos*2+1); else if(r<=mid) return query(l,r,pos*2); else return query(l,mid,pos*2)+query(mid+1,r,pos*2+1); } int main() { int x,q,i,t; while(~scanf("%d",&x)) { build_tree(1,x,1); scanf("%d",&q); while(q--) { int flag,change,l,r; scanf("%d%d%d",&flag,&l,&r); if(flag==1) { scanf("%d",&change); update(l,r,change,1); } else printf("%lld\n",query(l,r,1)); } } return 0; }
时间: 2024-10-08 16:27:53