treap分离合并 区间操作 poj 3468

来源:互联网 发布:逆战刷nz点软件 编辑:程序博客网 时间:2024/05/01 07:14
A Simple Problem with Integers
Time Limit: 5000MS Memory Limit: 131072KTotal Submissions: 53831 Accepted: 16158Case Time Limit: 2000MS

Description

You have N integers, A1, A2, ... ,AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1,A2, ... ,AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... ,Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4

Sample Output

455915

Hint

The sums may exceed the range of 32-bit integers.


题意很简单,区间增减,区间求和。

学习fhq treap,每一次区间操作把区间cut出来,操作完在merge回去,很神奇,debug两天,终于ac啦。

代码:

/* ***********************************************Author :xianxingwuguanCreated Time :2014/3/5 22:03:29File Name :1.cpp************************************************ */#pragma comment(linker, "/STACK:102400000,102400000")#include <stdio.h>#include <iostream>#include <algorithm>#include <sstream>#include <stdlib.h>#include <string.h>#include <limits.h>#include <string>#include <time.h>#include <math.h>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define INF 0x3f3f3f3f#define eps 1e-8#define pi acos(-1.0)typedef long long ll;ll ran(){static ll ranx=323232;return ranx+=ranx<<2|1;}struct Node{Node *l,*r;ll delta,sum,size,fix,key;}*root,*nill,mem[1101000];ll tot;void up(Node *o){if(o==nill)return;o->size=o->l->size+o->r->size+1;o->sum=o->key+o->delta;if(o->l!=nill)o->sum+=o->l->sum;if(o->r!=nill)o->sum+=o->r->sum;}void down(Node *o){if(o->delta){if(o->l!=nill)o->l->delta+=o->delta,o->l->sum+=o->l->size*o->delta,o->l->key+=o->delta;if(o->r!=nill)o->r->delta+=o->delta,o->r->sum+=o->r->size*o->delta,o->r->key+=o->delta;o->delta=0;}}void newnode(Node *&o,ll val){o=&mem[tot++];o->l=o->r=nill;o->size=1;o->fix=ran();o->sum=o->key=val;o->delta=0;}void cut(Node *o,Node *&a,Node *&b,int p) {        if (o->size <= p) a = o,b = nill;        else if (p==0) a = nill,b = o;        else {down(o);                if (o->l->size >= p){                     b = o;                     cut(o->l,a,b->l,p);                     up(b);                } else{                    a = o;                    cut(o->r,a->r,b,p - o->l->size - 1);                    up(a);                }        }}void merge(Node *&o,Node *a,Node *b){    if (a==nill) o = b;    else if (b==nill) o = a;    else{        if (a->fix> b->fix){     down(a);             o = a;             merge(o->r,a->r,b);        } else{down(b);            o = b;            merge(o->l,a,b->l);        }up(o);    }}void add(ll l,ll r,ll val){Node *a,*b,*c;cut(root,a,b,l-1);cut(b,b,c,r-l+1);b->key+=val;b->delta+=val;b->sum+=val*b->size;merge(a,a,b);merge(root,a,c);}ll query(ll l,ll r){Node *a,*b,*c;cut(root,a,b,l-1);cut(b,b,c,r-l+1);ll ans=b->sum;merge(b,b,c);merge(root,a,b);return ans;}void del(ll p) {     Node *a,*b,*c;     cut(root,a,b,p-1);     cut(b,b,c,1);     merge(root,a,c);}Node *Ins(ll x){if(x==0)return nill;if(x==1){int d;Node *a;scanf("%lld",&d);newnode(a,d);return a;}Node *a,*b;int m=x>>1;a=Ins(m);b=Ins(x-m);merge(a,a,b);return a;}void ins(ll pos,ll x){     ll d; Node *a,*b,*c,*t; cut(root,a,b,pos); c=Ins(x); merge(a,a,c); merge(root,a,b);}int main(){     //freopen("data.in","r",stdin);    // freopen("data.out","w",stdout);     ll i,j,k,m,n; while(~scanf("%lld%lld",&n,&m)){ tot=0; newnode(nill,0); nill->size=0; root=nill; ins(0,n); while(m--){ char op[3]; scanf("%s",op); if(op[0]=='Q'){ ll l,r; scanf("%lld%lld",&l,&r); printf("%lld\n",query(l,r)); } else { scanf("%lld%lld%lld",&i,&j,&k); add(i,j,k); } } /*Node *a,*b,*c; cut(root,a,b,0); cut(b,b,c,1); cout<<a->size<<" "<<b->size<<" "<<c->size<<endl; cout<<b->key<<" "<<b->delta<<" "<<b->sum<<endl; */ }     return 0;}/*10 157 2 3 4 5 6 7 8 9 10C 1 1 2C 1 1 10000C 2 2 1000C 1 3 3C 1 4 4C 1 5 5C 1 6 3C 1 7 7C 1 8 8C 1 9 9C 1 10 10Q 1 1Q 1 2Q 1 10Q 5 10*/


0 0
原创粉丝点击