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 }