很明显的线段树,果然比用伸展树舒服多了,没有太多的思路,就是区间成段的更新 还有 区间 求和操作,直接看代码
#include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<stack> #include<map> #include<vector> #include<cmath> #include<memory.h> #include<set> #define ll long long #define eps 1e-7 #define inf 0xfffffff const ll INF = 1ll<<61; using namespace std; //vector<pair<int,int> > G; //typedef pair<int,int > P; //vector<pair<int,int> > ::iterator iter; // //map<ll,int >mp; //map<ll,int >::iterator p; // typedef struct { int l,r; ll sum; ll add; }Node; int n,m; ll num[200000 + 5]; Node tree[200005 * 2]; ll build(int root,int left,int right) { int mid; ll x,y; tree[root].l = left; tree[root].r = right; tree[root].add = 0; if(left == right) { tree[root].sum = num[left]; return num[left]; } mid = (left + right)/2; x = build(root * 2,left,mid); y = build(root * 2 + 1,mid + 1,right); return tree[root].sum = x + y; } void insert(int root,int left,int right,int add) { if(left <= tree[root].l && tree[root].r <= right) { tree[root].add += add; tree[root].sum += add*(tree[root].r - tree[root].l + 1); return ; } if(tree[root].add) { tree[root * 2].sum += tree[root].add * (tree[root * 2].r - tree[root * 2].l + 1); tree[root * 2 + 1].sum += tree[root].add * (tree[root * 2 + 1].r - tree[root * 2 + 1].l + 1); tree[root * 2 ].add += tree[root].add; tree[root * 2 + 1].add += tree[root].add; tree[root].add = 0; } if(left <= (tree[root].l + tree[root].r)/2) insert(root * 2,left,right,add); if(right > (tree[root].l + tree[root].r)/2) insert(root * 2 + 1,left,right,add); tree[root].sum = tree[root * 2].sum + tree[root * 2 + 1].sum; } ll find(int root,int left,int right) { ll x = 0,y = 0; if(left <= tree[root].l && tree[root].r <= right) return tree[root].sum; if(tree[root].add) { tree[root * 2].sum += tree[root].add * (tree[root * 2].r -tree[root * 2].l + 1); tree[root * 2 + 1].sum += tree[root].add * (tree[root * 2 + 1].r - tree[root * 2 + 1].l + 1); tree[root * 2 ].add += tree[root].add; tree[root * 2 + 1].add += tree[root].add; tree[root].add = 0; } if(left <= (tree[root].l + tree[root].r)/2) x = find(root * 2,left,right); if(right > (tree[root].l + tree[root].r)/2) y = find(root * 2 + 1,left,right); return x + y; } int main() { char s[2]; int a,b,c; while(scanf("%d %d",&n,&m) == 2) { for(int i=1;i<=n;i++) scanf("%I64d",&num[i]); build(1,1,n); for(int i=0;i<m;i++) { scanf("%s",s); if(s[0] == ‘C‘) { scanf("%d %d %d",&a,&b,&c); if(a > b) { int tmp = a; a = b; b = tmp; } insert(1,a,b,c); } else { scanf("%d %d",&a,&b); if(a > b){ int tmp = a; a = b; b = tmp; } printf("%I64d\n",find(1,a,b)); } } } return EXIT_SUCCESS; }