problem
Description
给出一个N个整数构成的序列,有M次操作,每次操作有一下三种:
①Insert Y X,在序列的第Y个数之前插入一个数X;
②Add L R X,对序列中第L个数到第R个数,每个数都加上X;
③Query L R,询问序列中第L个数到第R个数的平方和。
Input
第一行一个正整数N,表示初始序列长度。
第二行N个整数Ai,表示初始序列中的数。
第三行一个正整数M,表示操作数。
接下来M行,每行一种操作。
Output
对于每一个Query操作输出答案。由于答案可能很大,请mod 7459后输出。
Sample Input
5
1 2 3 4 5
5
Query 1 3
Insert 2 5
Query 2 4
Add 5 6 7
Query 1 6
Sample Output
14
38
304
样例解释:
第二次操作后的序列:1,5,2,3,4,5。
第四次操作后的序列:1,5,2,3,11,12。
Data Constraint
30%的数据满足N≤1,000,M≤1,000。
另外20%的数据满足N≤100,000,M≤100,000,且不存在Insert操作。
100%的数据满足N≤100,000,M≤100,000,且Add和Insert操作中|X|≤1000,|Ai|≤1000。
analysis
splay例题好伐……?
通过左右旋维护两个东西,分别是和与平方和
每次一个位置 x 加上
a , sqrsum[x] 就会加上 a2∗size[x]+2a∗sum[x] , sum[x] 会加上 a∗size[x]然后就可以用splay查找来进行插入节点操作
然后愉快AC
code
#include<bits/stdc++.h>
#define MAXN 200001
#define mod 7459
using namespace std;
long long tree[MAXN][3],sum[MAXN],sqrsum[MAXN];
long long a[MAXN],father[MAXN],size[MAXN],flag[MAXN];
int n,m,root;
char s[11];
void downdata(int x)
{
if (!flag[x])return;
if (tree[x][1])
{
flag[tree[x][1]]+=flag[x];
}
if (tree[x][2])
{
flag[tree[x][2]]+=flag[x];
}
sqrsum[x]=(((sqrsum[x]+((flag[x]*flag[x])%mod)*size[x])%mod)+2*flag[x]*sum[x])%mod;
sum[x]=sum[x]+flag[x]*size[x];
tree[x][0]+=flag[x];
flag[x]=0;
}
void left_rotate(int x)
{
downdata(father[x]);
downdata(x);
int y=father[x],z=father[y];
father[x]=z,father[y]=x;
if (z==0)root=x;
else
{
if (tree[z][1]==y)
{
tree[z][1]=x;
}
else tree[z][2]=x;
}
if (tree[x][1])
{
father[tree[x][1]]=y;
}
tree[y][2]=tree[x][1];
tree[x][1]=y;
size[y]=size[tree[y][1]]+size[tree[y][2]]+1;
size[x]=size[y]+size[tree[x][2]]+1;
sum[y]=(sum[tree[y][1]]+sum[tree[y][2]]+tree[y][0])%mod;
sum[x]=(sum[y]+sum[tree[x][1]]+tree[x][0])%mod;
sqrsum[y]=(sqrsum[tree[y][1]]+sqrsum[tree[y][2]]+tree[y][0]*tree[y][0])%mod;
sqrsum[x]=(sqrsum[y]+sqrsum[tree[x][2]]+tree[x][0]*tree[x][0])%mod;
}
void right_rotate(int x)
{
downdata(father[x]);
downdata(x);
int y=father[x],z=father[y];
father[x]=z,father[y]=x;
if (z==0)root=x;
else
{
if (tree[z][1]==y)
{
tree[z][1]=x;
}
else tree[z][2]=x;
}
if (tree[x][2])
{
father[tree[x][2]]=y;
}
tree[y][1]=tree[x][2];
tree[x][2]=y;
size[y]=size[tree[y][1]]+size[tree[y][2]]+1;
size[x]=size[tree[x][1]]+size[y]+1;
sum[y]=(sum[tree[y][1]]+sum[tree[y][2]]+tree[y][0])%mod;
sum[x]=(sum[tree[x][1]]+sum[y]+tree[x][0])%mod;
sqrsum[y]=(sqrsum[tree[y][1]]+sqrsum[tree[y][2]]+tree[y][0]*tree[y][0])%mod;
sqrsum[x]=(sqrsum[tree[x][1]]+sqrsum[y]+tree[x][0]*tree[x][0])%mod;
}
void splay(int x,int y)
{
if (x==y || x==0)return;
while (father[x]!=y)
{
if (father[father[x]]==y)
{
if (tree[father[x]][1]==x)
{
right_rotate(x);
}
else left_rotate(x);
}
else
{
if (tree[father[father[x]]][1]==father[x] && tree[father[x]][1]==x)
{
right_rotate(father[x]);
right_rotate(x);
}
else if (tree[father[father[x]]][1]==father[x] && tree[father[x]][2]==x)
{
left_rotate(x);
right_rotate(x);
}
else if (tree[father[father[x]]][2]==father[x] && tree[father[x]][1]==x)
{
right_rotate(x);
left_rotate(x);
}
else if (tree[father[father[x]]][2]==father[x] && tree[father[x]][2]==x)
{
left_rotate(father[x]);
left_rotate(x);
}
}
}
}
int find(int x,int y)
{
if (tree[x][1])
{
downdata(tree[x][1]);
}
if (tree[x][2])
{
downdata(tree[x][2]);
}
if (y==size[tree[x][1]]+1)return x;
else
{
if (y<size[tree[x][1]]+1)return find(tree[x][1],y);
else return find(tree[x][2],y-size[tree[x][1]]-1);
}
}
int main()
{
//freopen("readin.txt","r",stdin);
scanf("%d",&n);
root=1,tree[1][2]=2;
for (int i=1;i<=n;i++)
{
scanf("%lld",&a[i+1]);
father[i+1]=i;
tree[i+1][0]=a[i+1];
tree[i+1][2]=i+2;
size[i+1]=n+2-i;
}
n+=2;
for (int i=n-1;i>=1;i--)
{
sum[i]=(sum[i+1]+a[i])%mod;
sqrsum[i]=(sqrsum[i+1]+a[i]*a[i])%mod;
}
size[1]=n,size[n]=1;
father[n]=n-1;
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
int x,y,z;
scanf("%s%d%d",&s,&x,&y);
if (s[0]=='Q')
{
int j=find(1,x),k=find(1,y+2);
splay(j,1),splay(k,j);
printf("%lld\n",(sqrsum[tree[k][1]]+mod)%mod);
}
else if (s[0]=='I')
{
int j=find(1,x),k=find(1,x+1);
splay(j,1),splay(k,j);
tree[++n][0]=y,tree[n][1]=tree[n][2]=0;
father[n]=k;
tree[k][1]=n;
sum[n]=y%mod,sqrsum[n]=y*y%mod;
size[n]=1;
sum[j]=(sum[j]+y)%mod,sum[k]=(sum[k]+y)%mod;
sqrsum[j]=(sqrsum[j]+y*y)%mod,sqrsum[k]=(sqrsum[k]+y*y)%mod;
size[j]++,size[k]++;
}
else
{
scanf("%d",&z);
int j=find(1,x),k=find(1,y+2);
splay(j,1),splay(k,j);
flag[tree[k][1]]+=z;
downdata(tree[k][1]);
}
}
return 0;
}