bzoj3323【scoi2013】多项式的运算

3323: [Scoi2013]多项式的运算 

Time Limit: 12 Sec   Memory Limit: 64 MB
Submit: 232   Solved: 69
[ Submit][ Status][ Discuss]

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
 
3.  将x^L 到x^R 这些项乘上x变量
4.  将某个定值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。

HINT

应上传者要求,此系列试题不公开,如有异议,本站将删除之。




同样是一道Splay维护区间的题。

第一、二种操作:Splau维护区间加或乘一个数,只需要打一个标记就可以了。

第三种操作:先将a[r]和a[r+1]合并,再在a[l]前插入一个数0,这里用到了区间上插入、删除或修改一个数。

第四种操作:因为出现次数最多为10次,所以可以暴力求解。

注意:每次操作之前要从上到下pushdown,操作之后要从下到上pushup。(类似线段树)




#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define LL long long
#define pa pair<int,int>
#define MAXN 200005
#define MAXM 100005
#define INF 1000000000
#define mod 20130426
using namespace std;
int rt,n,m,tot,t1,t2,c[MAXN][2],fa[MAXN];
LL v[MAXN],s[MAXN],t[MAXN][2],ans,base;
int read()
{
    int ret=0,flag=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') flag=-1;ch=getchar();}
    while (ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}
    return ret*flag;
}
inline void pushup(int k)
{
    s[k]=s[c[k][0]]+s[c[k][1]]+1;
}
inline void rotate(int x,int &k)
{
    int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1;
    if (y!=k) c[z][c[z][1]==y]=x;else k=x;
    fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
    c[y][l]=c[x][r];c[x][r]=y;
    pushup(y);pushup(x);
}
inline void splay(int x,int &k)
{
    while (x!=k)
    {
        int y=fa[x],z=fa[y];
        if (y!=k){if(c[y][0]==x^c[z][0]==y)rotate(x,k);else rotate(y,k);}
        rotate(x,k);
    }
}
inline void update(int k,LL x,LL y)
{
    if (!k) return;
    v[k]=(v[k]*y+x)%mod;
    t[k][0]=(t[k][0]*y+x)%mod;
    t[k][1]=(t[k][1]*y)%mod;
}
inline void pushdown(int k)
{
    if (!k) return;
    if (!t[k][0]&&t[k][1]==1) return;
    update(c[k][0],t[k][0],t[k][1]);
    update(c[k][1],t[k][0],t[k][1]);
    t[k][0]=0;t[k][1]=1;
}
inline int find(int k,int rank)
{
    pushdown(k);
    if (s[c[k][0]]+1==rank) return k;
    else if (s[c[k][0]]>=rank) return find(c[k][0],rank);
    else return find(c[k][1],rank-s[c[k][0]]-1);
}
inline void split(int l,int r)
{
    t1=find(rt,l);t2=find(rt,r);
    splay(t1,rt);splay(t2,c[rt][1]);
}
inline void getans(int k)
{
    if (!k) return;
    pushdown(k);
    getans(c[k][1]);
    if (k!=1) ans=(ans*base+v[k])%mod;
    getans(c[k][0]);
}
inline void build(int l,int r,int f)
{
    if (l>r) return;
    int mid=(l+r)>>1;
    fa[mid]=f;c[f][mid>f]=mid;
    s[mid]=1;t[mid][0]=0;t[mid][1]=1;
    if (l==r) return;
    build(l,mid-1,mid);build(mid+1,r,mid);
    pushup(mid);
}
inline void solvemul()
{
    int x=read()+1,y=read()+1;
    split(x,y+2);
    LL ad=0,mu=read()%mod;
    update(c[t2][0],ad,mu);
    pushup(t2);pushup(t1);
}
inline void solveadd()
{
    int x=read()+1,y=read()+1;
    split(x,y+2);
    LL ad=read()%mod,mu=1;
    update(c[t2][0],ad,mu);
    pushup(t2);pushup(t1);
}
inline void solvemulx()
{
    int x=read()+1,y=read()+1;
    split(y,y+3);
    int z=c[t2][0],zz=c[z][0]+c[z][1];
    pushdown(t1);pushdown(t2);pushdown(z);
    v[z]=(v[z]+v[zz])%mod;s[z]=1;
    fa[zz]=c[z][0]=c[z][1]=0;
    pushup(t2);pushup(t1);
    split(x,x+1);
    c[t2][0]=++tot;s[tot]=1;fa[tot]=t2;v[tot]=t[tot][0]=0;t[tot][1]=1;
    pushup(t2);pushup(t1);
}
inline void query()
{
    ans=0;base=read()%mod;
    getans(rt);
    printf("%lld\n",ans);
}
int main()
{
    build(1,MAXM,0);tot=MAXM;rt=(1+MAXM)>>1;
    m=read();char ch[10];
    while(m--)
    {
        scanf("%s",ch);
        if (strlen(ch)==3)
        {
            if (ch[0]=='m') solvemul();
            else solveadd();
        }
        else if (ch[3]=='x') solvemulx();
        else query();
    }
}


你可能感兴趣的:(bzoj)