poj3468 A Simple Problem with Integers

来源:互联网 发布:php分页代码 编辑:程序博客网 时间:2024/05/12 18:00

        题意:n个数,你可以给一个区间加上c,或者询问一个区间的和。

        思路:线段树(成段更新)。简直模版得不能再模板。。不过我还是因为不熟练写了好些bug。


#include <iostream>    #include <stdio.h>    #include <cmath>    #include <algorithm>    #include <iomanip>    #include <cstdlib>    #include <string>     #include <vector>    #include <queue>    #include <stack>    #include <map>  #include <set>  #include <ctype.h>    #define ll long longusing namespace std;  struct node{int l,r;ll val;ll add;};node tree[400010];ll num[100010];ll build_tree(int n,int l,int r){tree[n].l=l; tree[n].r=r; tree[n].add=0;if(l==r){tree[n].val=num[l];return num[l];}int mid=(l+r)/2;tree[n].val=build_tree(n*2,l,mid)+build_tree(n*2+1,mid+1,r);return tree[n].val;}void update(int n,int l,int r,ll v){tree[n].val+=(r-l+1)*v;if(tree[n].l==l&&tree[n].r==r){if(l!=r)tree[n].add+=v;return;}int mid=(tree[n].l+tree[n].r)/2;if(tree[n].add){update(n*2,tree[n].l,mid,tree[n].add);update(n*2+1,mid+1,tree[n].r,tree[n].add);tree[n].add=0;}if(r<=mid){update(n*2,l,r,v);}else{if(l<=mid){update(n*2,l,mid,v);update(n*2+1,mid+1,r,v);}else{update(n*2+1,l,r,v);}}}ll query(int n,int l,int r){if(tree[n].l==l&&tree[n].r==r){return tree[n].val;}int mid=(tree[n].l+tree[n].r)/2;if(tree[n].add){update(n*2,tree[n].l,mid,tree[n].add);update(n*2+1,mid+1,tree[n].r,tree[n].add);tree[n].add=0;}//if(r<=mid){return query(n*2,l,r);}else{if(l<=mid){return query(n*2,l,mid)+query(n*2+1,mid+1,r);}else{return query(n*2+1,l,r);}}}int main(){int n,q;while(cin>>n>>q){for(int i=1;i<=n;i++){scanf("%lld",&num[i]);}build_tree(1,1,n);while(q--){char str[10];scanf("%s",str);if(str[0]=='C'){int a,b,c;scanf("%d%d%d",&a,&b,&c);update(1,a,b,c);}else{int a,b;scanf("%d%d",&a,&b);ll ans=query(1,a,b);printf("%lld\n",ans);}}}return 0;} 


0 0
原创粉丝点击