BZOJ3323: [Scoi2013]多项式的运算
题解: 直接splay就好了 这题最大的亮点是 区间平移 我们可以通过把r和r+1节点合并 然后在l-1加上一个节点实现
#include <bits/stdc++.h> const int MAXN=3e5+10; const int inf=2e5+2; #define ll long long using namespace std; const int mod=20130426; int ch[MAXN][2],size[MAXN],pre[MAXN],rt,cnt; ll tag1[MAXN],tag2[MAXN],key[MAXN];//tag1 jia tag2 cheng void newnode(int &x,int y){ x=++cnt;ch[x][0]=ch[x][1]=0;key[x]=0;size[x]=1;pre[x]=y; tag1[x]=0;tag2[x]=1; } void add(int r,int vul){ if(!r)return ; vul%=mod; tag1[r]+=vul;key[r]+=vul; tag1[r]%=mod;key[r]%=mod; } void mul(int r,ll vul){ if(!r)return ; vul%=mod; tag2[r]*=1LL*vul;tag2[r]%=mod; tag1[r]*=1LL*vul;tag1[r]%=mod; key[r]*=1LL*vul;key[r]%=mod; } void push(int x){ if(tag2[x]!=1){ mul(ch[x][0],tag2[x]); mul(ch[x][1],tag2[x]); tag2[x]=1; } if(tag1[x]!=0){ add(ch[x][0],tag1[x]); add(ch[x][1],tag1[x]); tag1[x]=0; } } void up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;} void P(int x){ if(pre[x])P(pre[x]); push(x); } void rotate(int x,int kind){ int y=pre[x]; ch[y][!kind]=ch[x][kind];pre[ch[x][kind]]=y; if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x; pre[x]=pre[y];ch[x][kind]=y;pre[y]=x; up(y); } void splay(int x,int goal){ P(x); while(pre[x]!=goal){ if(pre[pre[x]]==goal)rotate(x,ch[pre[x]][0]==x); else{ int y=pre[x];int kind=ch[pre[y]][0]==y; if(ch[y][kind]==x)rotate(x,!kind),rotate(x,kind); else rotate(y,kind),rotate(x,kind); } } if(goal==0)rt=x; up(x); } int find1(int x,int sz){ push(rt); if(sz==size[ch[x][0]]+1)return x; else if(sz<=size[ch[x][0]])return find1(ch[x][0],sz); else return find1(ch[x][1],sz-size[ch[x][0]]-1); up(rt); } void Add(){ int l,r,v;scanf("%d%d%d",&l,&r,&v); splay(find1(rt,l+1),0);splay(find1(rt,r+3),rt); add(ch[ch[rt][1]][0],v); } void Mul(){ int l,r;ll v;scanf("%d%d%lld",&l,&r,&v); splay(find1(rt,l+1),0);splay(find1(rt,r+3),rt); mul(ch[ch[rt][1]][0],v); } void update(){ int l,r;scanf("%d%d",&l,&r); splay(find1(rt,r+1),0);splay(find1(rt,r+3),rt); int t=ch[ch[rt][1]][0];ch[ch[rt][1]][0]=0;up(ch[rt][1]);up(rt); pre[t]=0;splay(find1(rt,r+2),0);key[rt]+=key[t];key[rt]%=mod; size[t]=1;tag1[t]=0;tag2[t]=1;key[t]=0;ch[t][0]=ch[t][1]=0; splay(find1(rt,l+1),0);splay(find1(rt,l+2),rt); ch[ch[rt][1]][0]=t;pre[t]=ch[rt][1];up(ch[rt][1]);up(rt); } int st[MAXN],tot; void dfs(int x){ if(!x)return ; push(x); dfs(ch[x][0]); st[++tot]=key[x]; dfs(ch[x][1]); up(x); } void querty(){ ll v;scanf("%lld",&v); tot=0;ll ans=0;ll x=1; dfs(rt); for(int i=2;i<=tot;i++)ans=(ans+1LL*st[i]*x)%mod,x=x*v%mod; printf("%lld\n",ans); } void built(int &x,int l,int r,int y){ if(l>r)return ; int mid=(l+r)>>1; newnode(x,y); built(ch[x][0],l,mid-1,x); built(ch[x][1],mid+1,r,x); up(x); } void inte(){ newnode(rt,0);newnode(ch[rt][1],rt); built(ch[ch[rt][1]][0],1,inf,ch[rt][1]); up(ch[rt][1]);up(rt); } char str[11]; int main(){ inte(); int n;scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%s",str); if(str[0]=='a')Add(); else if(str[0]=='q')querty(); else{ int len=strlen(str); if(len==4)update(); else Mul(); } } return 0; }
3323: [Scoi2013]多项式的运算
Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 456 Solved: 166
[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
接下来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
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。
147
588
Hint
操作一之后,多项式为F(x) = 7x + 7。
操作三之后,多项式为F(x) = 49x + 49。
操作五之后,多项式为F(x) = 49x^2 + 49x。
HINT
应上传者要求,此系列试题不公开,如有异议,本站将删除之。