luogu3278/bzoj3323 多项式的运算 (splay)

mulx的操作,其实就是给r+1的系数+=r的系数,然后删掉r,把l~r-1向右移一位,再插一个0到原来的位置

splay维护区间加和区间乘就好了

(一定要注意做事的顺序,一件事都做完了再去做别的,否则一splay就全乱套了..)

  1 #include<bits/stdc++.h>
  2 #define pa pair<int,int>
  3 #define CLR(a,x) memset(a,x,sizeof(a))
  4 using namespace std;
  5 typedef long long ll;
  6 const int maxn=1e5+10,P=20130426;
  7 
  8 inline ll rd(){
  9     ll x=0;char c=getchar();int neg=1;
 10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
 11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
 12     return x*neg;
 13 }
 14 
 15 int fa[maxn],ch[maxn][2],siz[maxn],rt;
 16 ll v[maxn],ad[maxn],mp[maxn];
 17 
 18 inline bool isrc(int p){return p==ch[fa[p]][1];}
 19 
 20 inline void update(int p){siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;}
 21 
 22 inline void dealadd(int p,ll a){
 23     v[p]+=a,ad[p]+=a;
 24     v[p]%=P,ad[p]%=P;
 25 }
 26 inline void dealmult(int p,ll x){
 27     v[p]*=x,mp[p]*=x,ad[p]*=x;
 28     v[p]%=P,mp[p]%=P,ad[p]%=P;
 29 }
 30 
 31 inline void pushdown(int p){
 32     int a=ch[p][0],b=ch[p][1];
 33     if(a) dealmult(a,mp[p]),dealadd(a,ad[p]);
 34     if(b) dealmult(b,mp[p]),dealadd(b,ad[p]);
 35     mp[p]=1,ad[p]=0;
 36 }
 37 
 38 inline void rotate(int x){
 39     int f=fa[x],ff=fa[f];bool b=isrc(x);
 40     fa[x]=ff;if(ff) ch[ff][isrc(f)]=x;
 41     ch[f][b]=ch[x][!b];if(ch[x][!b]) fa[ch[x][!b]]=f;
 42     ch[x][!b]=f;fa[f]=x;
 43     update(f);update(x);
 44 }
 45 
 46 inline void splay(int x,int t){
 47     while(fa[x]!=t&&fa[fa[x]]!=t){
 48         if(isrc(x)==isrc(fa[x])) rotate(fa[x]);
 49         else rotate(x);rotate(x);
 50     }if(fa[x]!=t) rotate(x);
 51     if(!t) rt=x;
 52 }
 53 
 54 inline int findkth(int k){
 55     int x=rt;
 56     while(1){
 57         pushdown(x);
 58         int w=siz[ch[x][0]];
 59         if(k<=w) x=ch[x][0];
 60         else if(k>w+1) k-=w+1,x=ch[x][1];
 61         else return x;
 62     }
 63 }
 64 
 65 inline int split(int l,int r){
 66     int x=findkth(l);splay(x,0);
 67     int y=findkth(r+2);splay(y,x);
 68     return y;
 69 }
 70 
 71 inline void solvemul(int l,int r,ll x){
 72     int p=ch[split(l,r)][0];
 73     dealmult(p,x);pushdown(p);
 74     splay(p,0);
 75 }
 76 inline void solveadd(int l,int r,ll x){
 77     int p=ch[split(l,r)][0];
 78     dealadd(p,x);pushdown(p);
 79     splay(p,0);
 80 }
 81 inline int pop(int k){
 82     int q=split(k,k);
 83     int p=ch[q][0];
 84     fa[p]=0,ch[q][0]=0;
 85     update(q);splay(q,0);
 86     return p;
 87 }
 88 inline void solvemulx(int l,int r){
 89     int p=pop(r);
 90     int q=split(l,l-1);
 91     // printf("~~%d %d\n",p,q);
 92     fa[p]=q,ch[q][0]=p,siz[p]=1;
 93     int x=v[p];
 94     v[p]=ad[p]=0,mp[p]=1;splay(p,0);
 95     solveadd(r+1,r+1,x);
 96     
 97 }
 98 int pct;
 99 inline void build(int &p,int l,int r){
100     p=++pct;
101     int m=l+r>>1;p=m;mp[p]=1;
102     if(l<m) build(ch[p][0],l,m-1),fa[ch[p][0]]=p;
103     if(r>m) build(ch[p][1],m+1,r),fa[ch[p][1]]=p;
104     update(p);
105 }
106 
107 int tot,dfn[maxn];
108 void dfs(int x){
109     pushdown(x);
110     if(ch[x][0]) dfs(ch[x][0]);
111     dfn[++tot]=x;
112     if(ch[x][1]) dfs(ch[x][1]);
113 }
114 inline int query(ll x){
115     tot=0;dfs(rt);
116     ll re=0,y=1;
117     for(int i=2;i<tot;i++,y=y*x%P){
118         re+=y*v[dfn[i]]%P,re%=P;
119     }
120     return re;
121 }
122 
123 int main(){
124     //freopen(".in","r",stdin);
125     int i,j,k;
126     int N=rd();
127     build(rt,1,1e5+3);
128     for(i=1;i<=N;i++){
129         char s[10];
130         scanf("%s",s);
131         if(s[0]=='a'){
132             int a=rd(),b=rd(),c=rd();
133             solveadd(a+1,b+1,c);
134         }else if(strlen(s)==4){
135             int a=rd(),b=rd();
136             solvemulx(a+1,b+1);
137         }else if(s[0]=='m'){
138             int a=rd(),b=rd(),c=rd();
139             solvemul(a+1,b+1,c);
140         }else if(s[0]=='q'){
141             printf("%d\n",query(rd()));
142         }
143     }
144     return 0;
145 }

 

posted @ 2018-11-09 14:49  Ressed  阅读(273)  评论(0编辑  收藏  举报