Description
某天,mzry1992 一边思考着一个项目问题一边在高速公路上骑着摩托车。一个光头踢了他一脚,摩托车损坏,而他也被送进校医院打吊针。现在该项目的截止日期将近,他不得不请你来帮助他完成这个项目。该项目的目的是维护一个动态的关于x 的无穷多项式F(x) = a0 * x^0 + a1 * x^1 + a2 * x^2 + … ,这个多项式初始时对于所有i有ai = 0。
操作者可以进行四种操作:
1. 将x^L 到x^R 这些项的系数乘上某个定值v
2. 将x^L 到x^R 这些项的系数加上某个定值v
输入的第一行有一个整数n 代表操作的个数。
接下来n 行,每行一个操作,格式如下:
mul L R v 代表第一种操作
add L R v 代表第二种操作
mulx L R 代表第三种操作
query v 代表第四种操作
对于30% 的数据:N <= 5000,0 <= L <= R <= 5000,0 <= v <= 10^9
另有20% 的数据:N <= 10^5,0 <= L <= R <= 10^5,0 <= v <= 10^9,没有mulx 操作
剩下的50% 的数据:N <= 10^5,0 <= L <= R <= 10^5,0 <= v <= 10^9
Output
对于每个query 操作,输出对应的答案,结果可能较大,需要模上20130426。
Sample Input
6
add 0 1 7
query 1
mul 0 1 7
query 2
mulx 0 1
query 3
Sample Output
14
147
588
Hint
操作一之后,多项式为F(x) = 7x + 7。
操作三之后,多项式为F(x) = 49x + 49。
操作五之后,多项式为F(x) = 49x^2 + 49x。
HINT
应上传者要求,此系列试题不公开,如有异议,本站将删除之。
Source
学了下Splay维护多项式.
难点主要在那个mulx操作,要把两项合并一下
这题卡常数,有毒!
#include
#include
#include
#include
#include
#define MAXN 1000010
#define SIZE 100010
#define P 20130426
#define LL long long
#define GET (ch>='0'&&ch<='9')
using namespace std;
int n,x,y,v;
char ch[10];
int root,cnt;
LL ans;
inline void in(int &x)
{
char ch=getchar();x=0;
while (!GET) ch=getchar();
while (GET) x=x*10+ch-'0',ch=getchar();
}
struct splay
{
int ch[2],fa,size;
LL val,add,mul;
}tree[MAXN];
inline void push_up(int x)
{
tree[x].size=tree[tree[x].ch[0]].size+tree[tree[x].ch[1]].size+1;
}
inline void push_down(int x)
{
if (!x) return;
if (tree[x].add==0&&tree[x].mul==1) return;
int l=tree[x].ch[0],r=tree[x].ch[1];
((tree[l].val*=tree[x].mul)+=tree[x].add)%=P;
((tree[l].add*=tree[x].mul)+=tree[x].add)%=P;
(tree[l].mul*=tree[x].mul)%=P;
((tree[r].val*=tree[x].mul)+=tree[x].add)%=P;
((tree[r].add*=tree[x].mul)+=tree[x].add)%=P;
(tree[r].mul*=tree[x].mul)%=P;
tree[x].add=0;tree[x].mul=1;
}
inline void rot(int x,int &f)
{
int y=tree[x].fa,z=tree[y].fa,l,r;
l=(tree[y].ch[1]==x);r=l^1;
if (y==f) f=x;
else tree[z].ch[tree[z].ch[1]==y]=x;
tree[tree[x].ch[r]].fa=y;tree[y].fa=x;tree[x].fa=z;
tree[y].ch[l]=tree[x].ch[r];tree[x].ch[r]=y;
push_up(y);push_up(x);
}
inline void Splay(int x,int &f)
{
while (x!=f)
{
int y=tree[x].fa,z=tree[y].fa;
if (y!=f)
{
if ((tree[y].ch[0]==x)^(tree[z].ch[0]==y)) rot(x,f);
else rot(y,f);
}
rot(x,f);
}
}
inline int find(int x,int k)
{
push_down(x);
int l=tree[x].ch[0],r=tree[x].ch[1];
if (tree[l].size+1==k) return x;
if (tree[l].size>=k) return find(l,k);
else return find(r,k-tree[l].size-1);
}
inline void split(int l,int r)
{
x=find(root,l);y=find(root,r);
Splay(x,root);Splay(y,tree[x].ch[1]);
}
inline void calc(int x)
{
if (!x) return;
push_down(x);
calc(tree[x].ch[1]);
if (x!=1) ans=(ans*v+tree[x].val)%P;
calc(tree[x].ch[0]);
}
inline void build(int l,int r,int f)
{
if (l>r) return;
int mid=(l+r)>>1;
tree[mid].fa=f;tree[f].ch[mid>f]=mid;
tree[mid].size=1;tree[mid].add=0;tree[mid].mul=1;
if (l==r) return;
build(l,mid-1,mid);build(mid+1,r,mid);
push_up(mid);
}
int main()
{
in(n);int L,R,V;
build(1,SIZE,0);root=(1+SIZE)>>1;cnt=SIZE;
while (n--)
{
scanf("%s",ch);
if (ch[0]=='m'&&ch[3]!='x')
{
in(L);in(R);L++;R++;in(V);V%=P;
split(L,R+2);int now=tree[y].ch[0];
(tree[now].val*=V)%=P;(tree[now].add*=V)%=P;(tree[now].mul*=V)%=P;
push_up(y);push_up(x);
}
if (ch[0]=='a')
{
in(L);in(R);L++;R++;in(V);V%=P;
split(L,R+2);int now=tree[y].ch[0];
(tree[now].val+=V)%=P;(tree[now].add+=V)%=P;
push_up(y);push_up(x);
}
if (ch[3]=='x')
{
in(L);in(R);L++;R++;
split(R,R+3);int now1=tree[y].ch[0],now2=tree[now1].ch[0]+tree[now1].ch[1];
push_down(x);push_down(y);push_down(now1);
tree[now1].val+=tree[now2].val;tree[now1].size=1;
tree[now2].fa=tree[now1].ch[0]=tree[now1].ch[1]=0;
push_up(y);push_up(x);
split(L,L+1);
tree[y].ch[0]=++cnt;tree[cnt].size=1;
tree[cnt].val=0;tree[cnt].fa=y;tree[cnt].add=0;tree[cnt].mul=1;
push_up(y);push_up(x);
}
if (ch[0]=='q')
{
ans=0;in(v);v%=P;
calc(root);printf("%lld\n",ans);
}
}
}