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

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

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

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

 #include<bits/stdc++.h>
#define pa pair<int,int>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=1e5+,P=; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int fa[maxn],ch[maxn][],siz[maxn],rt;
ll v[maxn],ad[maxn],mp[maxn]; inline bool isrc(int p){return p==ch[fa[p]][];} inline void update(int p){siz[p]=siz[ch[p][]]+siz[ch[p][]]+;} inline void dealadd(int p,ll a){
v[p]+=a,ad[p]+=a;
v[p]%=P,ad[p]%=P;
}
inline void dealmult(int p,ll x){
v[p]*=x,mp[p]*=x,ad[p]*=x;
v[p]%=P,mp[p]%=P,ad[p]%=P;
} inline void pushdown(int p){
int a=ch[p][],b=ch[p][];
if(a) dealmult(a,mp[p]),dealadd(a,ad[p]);
if(b) dealmult(b,mp[p]),dealadd(b,ad[p]);
mp[p]=,ad[p]=;
} inline void rotate(int x){
int f=fa[x],ff=fa[f];bool b=isrc(x);
fa[x]=ff;if(ff) ch[ff][isrc(f)]=x;
ch[f][b]=ch[x][!b];if(ch[x][!b]) fa[ch[x][!b]]=f;
ch[x][!b]=f;fa[f]=x;
update(f);update(x);
} inline void splay(int x,int t){
while(fa[x]!=t&&fa[fa[x]]!=t){
if(isrc(x)==isrc(fa[x])) rotate(fa[x]);
else rotate(x);rotate(x);
}if(fa[x]!=t) rotate(x);
if(!t) rt=x;
} inline int findkth(int k){
int x=rt;
while(){
pushdown(x);
int w=siz[ch[x][]];
if(k<=w) x=ch[x][];
else if(k>w+) k-=w+,x=ch[x][];
else return x;
}
} inline int split(int l,int r){
int x=findkth(l);splay(x,);
int y=findkth(r+);splay(y,x);
return y;
} inline void solvemul(int l,int r,ll x){
int p=ch[split(l,r)][];
dealmult(p,x);pushdown(p);
splay(p,);
}
inline void solveadd(int l,int r,ll x){
int p=ch[split(l,r)][];
dealadd(p,x);pushdown(p);
splay(p,);
}
inline int pop(int k){
int q=split(k,k);
int p=ch[q][];
fa[p]=,ch[q][]=;
update(q);splay(q,);
return p;
}
inline void solvemulx(int l,int r){
int p=pop(r);
int q=split(l,l-);
// printf("~~%d %d\n",p,q);
fa[p]=q,ch[q][]=p,siz[p]=;
int x=v[p];
v[p]=ad[p]=,mp[p]=;splay(p,);
solveadd(r+,r+,x); }
int pct;
inline void build(int &p,int l,int r){
p=++pct;
int m=l+r>>;p=m;mp[p]=;
if(l<m) build(ch[p][],l,m-),fa[ch[p][]]=p;
if(r>m) build(ch[p][],m+,r),fa[ch[p][]]=p;
update(p);
} int tot,dfn[maxn];
void dfs(int x){
pushdown(x);
if(ch[x][]) dfs(ch[x][]);
dfn[++tot]=x;
if(ch[x][]) dfs(ch[x][]);
}
inline int query(ll x){
tot=;dfs(rt);
ll re=,y=;
for(int i=;i<tot;i++,y=y*x%P){
re+=y*v[dfn[i]]%P,re%=P;
}
return re;
} int main(){
//freopen(".in","r",stdin);
int i,j,k;
int N=rd();
build(rt,,1e5+);
for(i=;i<=N;i++){
char s[];
scanf("%s",s);
if(s[]=='a'){
int a=rd(),b=rd(),c=rd();
solveadd(a+,b+,c);
}else if(strlen(s)==){
int a=rd(),b=rd();
solvemulx(a+,b+);
}else if(s[]=='m'){
int a=rd(),b=rd(),c=rd();
solvemul(a+,b+,c);
}else if(s[]=='q'){
printf("%d\n",query(rd()));
}
}
return ;
}
上一篇:Flutter Web实战项目打造真正跨平台应用(windows,android,ios,linux,macos,web)


下一篇:POJ2891 Strange Way to Express Integers [中国剩余定理]