P4715 「英语」Z 语言
题解:
平衡树维护hash值
为了支持加入删除操作 x*base^y 其中y为他是第k大
同一般的维护方法,我们不用对每个节点维护他的hash值
而是只用记录他的x值(他的位置) 然后通过updata的时候维护
很神奇的一点是
我用了mo数就炸了。。。
直接自然溢出就好了。。。应该是哪里正负没处理好。。
另外还wa了一个点。。
代码:
#include <bits/stdc++.h> using namespace std; #define ll long long const ll N=5e5+10; const ll Base=20020415; ll n,m,q,cl[N],a[N],b[N]; map<ll,ll> M; struct Splay{ ll count2[N],data[N],ls[N],rs[N],fa[N],v[N],vv[N],root=0,cnt=0; void updata(ll x) { count2[x]=count2[ls[x]]+count2[rs[x]]+1; data[x]=(data[ls[x]]+1ll*data[rs[x]]*cl[count2[ls[x]]+1] +cl[count2[ls[x]]]*v[x]); } void rotate(ll x,ll y) { ll fa1=fa[x]; if (y==1) { rs[fa1]=ls[x]; if (ls[x]) fa[ls[x]]=fa1; } else { ls[fa1]=rs[x]; if (rs[x]) fa[rs[x]]=fa1; } fa[x]=fa[fa1]; if (fa[fa1]) { ls[fa[fa1]]==fa1?ls[fa[fa1]]=x:rs[fa[fa1]]=x; } fa[fa1]=x; if (y==1) ls[x]=fa1; else rs[x]=fa1; updata(fa1); updata(x); } void splay(ll x,ll goal) { ll fa1=fa[x]; while (fa1!=goal) { if (fa[fa1]==goal) x==ls[fa1]?rotate(x,2):rotate(x,1); else if (fa1==ls[fa[fa1]]) if (x==ls[fa1]) rotate(fa1,2),rotate(x,2); else rotate(x,1),rotate(x,2); else if (x==rs[fa1]) rotate(fa1,1),rotate(x,1); else rotate(x,2),rotate(x,1); fa1=fa[x]; } if (!goal) root=x; } ll search(ll goal) { ll x=root; while (x) { if (vv[x]==goal) return(x); if (vv[x]<goal) x=rs[x]; else x=ls[x]; } } void ins(ll y,ll x1) { ll x=root; while (x) { if (y>vv[x]) if (rs[x]) x=rs[x]; else break; else if (ls[x]) x=ls[x]; else break; } if (!x) root=++cnt; else { if (y>vv[x]) { rs[x]=++cnt; fa[cnt]=x; } else { ls[x]=++cnt; fa[cnt]=x; } } vv[cnt]=y; v[cnt]=x1; count2[cnt]=1; splay(cnt,0); } void del(ll x1) { ll x=search(x1); splay(x,0); if (!ls[x]) { root=rs[root]; fa[root]=0; return; } ll y=ls[x]; while (rs[y]) y=rs[y]; rs[y]=rs[x]; if (rs[y]) fa[rs[y]]=y; updata(y); root=ls[x]; fa[ls[x]]=0; splay(y,0); } }A,B; int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); ios::sync_with_stdio(false); cl[0]=1; for (ll i=1;i<N;i++) cl[i]=(1ll*cl[i-1]*Base); cin>>n>>m>>q; ll cnt=0; for (ll i=0;i<m;i++) cnt+=cl[i]; for (ll i=1;i<=n;i++) cin>>a[i]; for (ll i=1;i<=m;i++) A.ins(a[i],i); ++M[A.data[A.root]]; for (ll i=m+1;i<=n;i++) { A.del(a[i-m]); A.ins(a[i],i); ll tmp=A.data[A.root]-1ll*cnt*(i-m); ++M[tmp]; } for (ll i=1;i<=m;i++) { cin>>b[i]; B.ins(b[i],i); } for (ll i=1;i<=q;i++) { ll x,y; cin>>x>>y; B.del(b[x]); b[x]=y; B.ins(y,x); cout<<M[B.data[B.root]]<<endl; } return 0; }