A Simple Problem with Integers
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. 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
The sums may exceed the range of 32-bit integers.
Source
POJ Monthly--2007.11.25, Yang Yi
|
题目:http://poj.org/problem?id=3468
分析:这题只是一道线段树的题,由于傻崽大神的splay模板就是这题,只好将就着做了= =,用splay实在很慢啊
ps:近期状态稍微恢复,之前没状态,完全看不懂模板啊
等做些题后再整理成模板= =
代码(只是稍微改改风格而已):
#include<cstdio>
const int mm=222222;
int num[mm];
struct SplayTree
{
int C[mm][2],S[mm],F[mm],val[mm],add[mm];
int root,size,l,r,d;
long long sum[mm];
void rotate(int x,int f)
{
int y=F[x];
pushdown(y);
pushdown(x);
C[y][!f]=C[x][f];
F[C[x][f]]=y;
F[x]=F[y];
if(F[x])C[F[y]][C[F[y]][1]==y]=x;
C[x][f]=y;
F[y]=x;
updata(y);
}
void splay(int x,int goal)
{
pushdown(x);
while(F[x]!=goal)
if(F[F[x]]==goal)rotate(x,C[F[x]][0]==x);
else
{
int y=F[x],f=(C[F[y]][0]==y);
if(C[y][f]==x)rotate(x,!f);
else rotate(y,f);
rotate(x,f);
}
updata(x);
if(!goal)root=x;
}
void select(int k,int goal)
{
int x=root;
pushdown(x);
while(S[C[x][0]]!=k)
{
if(S[C[x][0]]>k)x=C[x][0];
else k-=(S[C[x][0]]+1),x=C[x][1];
pushdown(x);
}
splay(x,goal);
}
void plus(int x,int d)
{
add[x]+=d;
sum[x]+=(long long)d*S[x];
}
void pushdown(int x)
{
if(add[x])
{
val[x]+=add[x];
for(int i=0;i<2;++i)plus(C[x][i],add[x]);
add[x]=0;
}
}
void updata(int x)
{
S[x]=S[C[x][0]]+S[C[x][1]]+1;
sum[x]=add[x]+val[x]+sum[C[x][0]]+sum[C[x][1]];
}
void newnode(int &x,int v)
{
x=++size;
C[x][0]=C[x][1]=F[x]=0;
sum[x]=val[x]=v;
S[x]=1;
add[x]=0;
}
void make(int &x,int l,int r,int f)
{
if(l>r)return;
int m=(l+r)>>1;
newnode(x,num[m]);
make(C[x][0],l,m-1,x);
make(C[x][1],m+1,r,x);
F[x]=f;
updata(x);
}
void prepare(int n)
{
C[0][0]=C[0][1]=S[0]=F[0]=0;
val[0]=sum[0]=add[0]=0;
root=size=0;
newnode(root,0);
newnode(C[root][1],0);
F[size]=root;
S[root]=2;
make(C[C[root][1]][0],0,n-1,C[root][1]);
updata(C[root][1]);
updata(root);
}
void addnum()
{
scanf("%d%d%d",&l,&r,&d);
select(l-1,0);
select(r+1,root);
plus(C[C[root][1]][0],d);
}
void answer()
{
scanf("%d%d",&l,&r);
select(l-1,0);
select(r+1,root);
printf("%lld\n",sum[C[C[root][1]][0]]);
}
}spt;
int main()
{
int i,n,m;
char op[2];
scanf("%d%d",&n,&m);
for(i=0;i<n;++i)scanf("%d",&num[i]);
spt.prepare(n);
while(m--)
{
scanf("%s",op);
if(op[0]=='C')spt.addnum();
else spt.answer();
}
return 0;
}