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
- 将x^L 到x^R 这些项乘上x变量
- 将某个定值v代入多项式F(x),并输出代入后多项式的值,之后多项式还原为代入前的状况
经过观察,项目组发现使用者的操作集中在前三种,第四种操作不会出现超过10次。mzry1992 负责这个项目的核心代码,你能帮他实现么。
Input
输入的第一行有一个整数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。
解题思路:
这题无旋treap好些一点,不过有点卡。
主要是mulx操作如何处理:将(r,r)的系数加到(r+1,r+1)上,再在(l,r-1)左边插入一个系数为0的节点即可。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());
if(c=='-')f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
const int N=100005,mod=20130426;
int n,m,tot,root,fa[N],pri[N],son[N][2],size[N];
int ans,x,curx,a[N],add[N],mul[N];char s[5];
inline int upt(int u)
{
size[u]=size[son[u][0]]+size[son[u][1]]+1;
return u;
}
void pushdown(int u)
{
int l=son[u][0],r=son[u][1],k=mul[u],b=add[u];
if(l)a[l]=(1ll*a[l]*k+b)%mod,add[l]=(1ll*add[l]*k+b)%mod,mul[l]=1ll*mul[l]*k%mod;
if(r)a[r]=(1ll*a[r]*k+b)%mod,add[r]=(1ll*add[r]*k+b)%mod,mul[r]=1ll*mul[r]*k%mod;
mul[u]=1,add[u]=0;
}
int merge(int u,int v)
{
if(!u)return upt(v);
if(!v)return upt(u);
if(pri[u]<pri[v])
{
pushdown(u),son[u][1]=merge(son[u][1],v);
return upt(u);
}
else
{
pushdown(v),son[v][0]=merge(u,son[v][0]);
return upt(v);
}
}
void split(int u,int kth,int &L,int &R)
{
if(!u){L=R=0;return;}
pushdown(u);
if(size[son[u][0]]<kth)
{
split(son[u][1],kth-size[son[u][0]]-1,L,R);
son[u][1]=L,L=u,upt(u);
}
else
{
split(son[u][0],kth,L,R);
son[u][0]=R,R=u,upt(u);
}
}
void Add(int l,int r,int b)
{
int L=0,R=0,p=0,q=0;
split(root,l-1,L,R);
split(R,r-l+1,p,q);
a[p]=(a[p]+b)%mod,add[p]=(add[p]+b)%mod;
root=merge(merge(L,p),q);
}
void Mul(int l,int r,int k)
{
int L=0,R=0,p=0,q=0;
split(root,l-1,L,R);
split(R,r-l+1,p,q);
a[p]=1ll*a[p]*k%mod,add[p]=1ll*add[p]*k%mod,mul[p]=1ll*mul[p]*k%mod;
root=merge(merge(L,p),q);
}
void Mulx(int l,int r)
{
int L=0,R=0,p=0,q=0,w=0,x=0,y=0,z=0;
split(root,l-1,L,R),split(R,r+1-l+1,p,q),split(p,r-l+1,x,y);
split(x,r-1-l+1,w,z);
a[y]=(a[y]+a[z])%mod,a[z]=0;
root=merge(merge(merge(merge(L,z),w),y),q);
}
int query(int u)
{
pushdown(u);
if(son[u][0])query(son[u][0]);
ans=(1ll*a[u]*curx+ans)%mod;curx=1ll*curx*x%mod;
if(son[u][1])query(son[u][1]);
}
int main()
{
//freopen("lx.in","r",stdin);
//freopen("lx.out","w",stdout);
m=getint();n=100001;int l,r;
for(int i=0;i<=n;i++)
{
a[++tot]=0,pri[tot]=rand(),mul[tot]=1;
root=merge(root,tot);
}
while(m--)
{
scanf("%s",s);
if(s[0]=='a')l=getint()+1,r=getint()+1,Add(l,r,getint());
else if(s[0]=='q')ans=0,curx=1,x=getint(),query(root),printf("%d\n",ans);
else if(s[3]=='x')l=getint()+1,r=getint()+1,Mulx(l,r);
else l=getint()+1,r=getint()+1,Mul(l,r,getint());
}
return 0;
}