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;
}

 

posted @ 2018-07-03 08:52  尹吴潇  阅读(187)  评论(0编辑  收藏  举报