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

来源:互联网 发布:.space是什么域名 编辑:程序博客网 时间:2024/05/17 06:58

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<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#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);        }    }}
1 0