Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 54382 | Accepted: 16350 | |
Case 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 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4
Sample Output
4 55 9 15
Hint
照着练一下splay。
代码:
/* ***********************************************
Author :rabbit
Created Time :2014/3/22 15:21:19
File Name :13.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;
#define keytree ch[ch[root][1]][0]
const ll maxn=200100;
struct splay{
ll sz[maxn],ch[maxn][2],pre[maxn];
ll root,top1,top2;
ll ss[maxn],que[maxn];
void Rotate(ll x,ll f){
ll y=pre[x];
pushdown(y);
pushdown(x);
ch[y][!f]=ch[x][f];
pre[ch[x][f]]=y;
pre[x]=pre[y];
if(pre[x])ch[pre[y]][ch[pre[y]][1]==y]=x;
ch[x][f]=y;
pre[y]=x;
pushup(y);
}
void Splay(ll x,ll goal){
pushdown(x);
while(pre[x]!=goal){
if(pre[pre[x]]==goal)Rotate(x,ch[pre[x]][0]==x);
else{
ll y=pre[x],z=pre[y];
ll f=ch[z][0]==y;
if(ch[y][f]==x)Rotate(x,!f),Rotate(x,f);
else Rotate(y,f),Rotate(x,f);
}
}
pushup(x);
if(goal==0)root=x;
}
void RTO(ll k,ll goal){
ll x=root;
pushdown(x);
while(sz[ch[x][0]]!=k){
if(k<sz[ch[x][0]])x=ch[x][0];
else{
k-=sz[ch[x][0]]+1;
x=ch[x][1];
}
pushdown(x);
}
Splay(x,goal);
}
void erase(ll x){
ll father=pre[x];
ll head=0,tail=0;
for(que[tail++]=x;head<tail;head++){
ss[top2++]=que[head];
if(ch[que[head]][0])que[tail++]=ch[que[head]][0];
if(ch[que[head]][1])que[tail++]=ch[que[head]][1];
}
ch[father][ch[father][1]==x]=0;
pushup(father);
}
void debug(){
printf("%lld\n",root);
Traval(root);
}
void Traval(ll x){
if(x){
Traval(ch[x][0]);
printf("结点%2lld:左儿子 %2lld 右儿子 %2lld 父结点 %2lld size = %2lld ,val = %2lld\n",x,ch[x][0],ch[x][1],pre[x],sz[x],val[x]);
Traval(ch[x][1]);
}
}
ll val[maxn],num[maxn],add[maxn],sum[maxn];
void Newnode(ll &x,ll c){
if(top2)x=ss[--top2];else x=++top1;
ch[x][0]=ch[x][1]=pre[x]=0;
sz[x]=1;
val[x]=sum[x]=c;
add[x]=0;
}
void pushdown(ll x){
if(add[x]){
val[x]+=add[x];
add[ch[x][0]]+=add[x];
add[ch[x][1]]+=add[x];
sum[ch[x][0]]+=sz[ch[x][0]]*add[x];
sum[ch[x][1]]+=sz[ch[x][1]]*add[x];
add[x]=0;
}
}
void pushup(ll x){
sz[x]=1+sz[ch[x][0]]+sz[ch[x][1]];
sum[x]=add[x]+val[x]+sum[ch[x][0]]+sum[ch[x][1]];
}
void Build(ll &x,ll l,ll r,ll f){
if(l>r)return;
ll m=(l+r)/2;
Newnode(x,num[m]);
Build(ch[x][0],l,m-1,x);
Build(ch[x][1],m+1,r,x);
pre[x]=f;
pushup(x);
}
void init(ll n){
ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;
add[0]=sum[0]=0;
Newnode(root,-1);
Newnode(ch[root][1],-1);
pre[top1]=root;
sz[root]=2;
for(ll i=0;i<n;i++)scanf("%lld",&num[i]);
Build(keytree,0,n-1,ch[root][1]);
pushup(ch[root][1]);
pushup(root);
}
void update(ll l,ll r,ll c){
RTO(l-1,0);
RTO(r+1,root);
add[keytree]+=c;
sum[keytree]+=c*sz[keytree];
}
ll query(ll l,ll r){
RTO(l-1,0);
RTO(r+1,root);
return sum[keytree];
}
}spt;
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
ll n,m;
while(~scanf("%lld%lld",&n,&m)){
spt.init(n);
while(m--){
char op[2];
scanf("%s",op);
if(op[0]=='Q'){
ll l,r,c;
scanf("%lld%lld",&l,&r);
printf("%lld\n",spt.query(l,r));
}
else{
ll l,r,c;
scanf("%lld%lld%lld",&l,&r,&c);
spt.update(l,r,c);
}
}
}
return 0;
}