【SCOI2013】【BZOJ3323】多项式的运算

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

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

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

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);
        }
    }
}

你可能感兴趣的:(随便搞搞,丧心病狂,奇怪的姿势)