莫队求助QAQ
查看原帖
莫队求助QAQ
147401
koishi_offical楼主2021/6/16 21:35

只能过第一个点和第四个点 怀疑是值域分块写歪了

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10,inf=2147483647;
struct node
  {
      int l,r;
      int p;
      int num;
      int k;
      int id;
  }q[N];
struct ch
  {
      int from,to;
      int p;
  } c[N];
int n,m,t;
int maxn;
int maxm;
int maxq,maxc;
int a[N],typ[N];
int bl[N],sq;
bool cmp(node x,node y)
  {
      if(bl[x.l]!=bl[y.l]) return x.l<y.l;
      if(x.r!=y.r) return x.r<y.r;
      return x.k>y.k;
  }
int sn,b[N],bn[N],lbn[N],rbn[N],sum[N];
void change(int from,int to)
  {
      b[from]--;
      b[to]++;
      sum[bn[from]]--;
      sum[bn[to]]++;
  }
int get_rank(int x)
  {
      int i=1;
      int ans=0;
      while(rbn[i]<x&&i<t)
        {
            ans+=sum[i];
            i++;
        }
      int k=lbn[i];
      while(k<x&&k<rbn[i]) ans+=b[k],k++;
      return ans+1;
  }
int get_key(int x)
  {
      int i=1;
      while(x>sum[i]&&i<=t)
        {
            x-=sum[i];
            i++;
        }
      if(i>t) return typ[rbn[i-1]];
      int k=lbn[i];
      while(x>b[k]&&k<=rbn[i])
        {
            x-=b[k];
            k++;
        }
      return typ[k];
  }
int ans[N];
signed main() {
    cin>>n>>m;
    sq=pow(n,0.6666);
    for(int i=1;i<=n;i++)
      {
          bl[i]=(i-1)/sq+1;
          cin>>a[i];
          typ[++maxn]=a[i];
      }
    for(int i=1;i<=m;i++)
      {
          int op;
          cin>>op;
          if(op==1)
            {
                int x,l,r;
                cin>>l>>r>>x;
                int p=++maxq;
                q[p].l=l;
                q[p].r=r;
                q[p].p=x;
                q[p].k=maxc;
                q[p].num=1;
                q[p].id=p;
                typ[++maxn]=x;
            }
          if(op==2)
            {
                int x,l,r;
                cin>>l>>r>>x;
                int p=++maxq;
                q[p].l=l;
                q[p].r=r;
                q[p].p=x;
                q[p].k=maxc;
                q[p].id=p;
                q[p].num=2;
            }
          if(op==3)
            {
                int p,v;
                cin>>p>>v;
                c[++maxc].from=a[p];
                c[maxc].to=v;
                c[maxc].p=p;
                typ[++maxn]=v;
                a[p]=v;
            }
          if(op==4)
            {
                int x,l,r;
                cin>>l>>r>>x;
                int p=++maxq;
                q[p].l=l;
                q[p].r=r;
                q[p].p=x;
                q[p].num=4;
                q[p].k=maxc;
                q[p].id=p;
                typ[++maxn]=x;
            }
          if(op==5)
            {
                int x,l,r;
                cin>>l>>r>>x;
                int p=++maxq;
                q[p].l=l;
                q[p].r=r;
                q[p].p=x;
                q[p].num=5;
                q[p].k=maxc;
                q[p].id=p;
                typ[++maxn]=x;
            }
      }
    sort(q+1,q+maxq+1,cmp);
    sort(typ+1,typ+maxn+1);
    maxm=unique(typ+1,typ+maxn+1)-typ-1;
    sn=sqrt(maxm);
    t=maxm/sn;
    for(int i=1;i<=t;i++) {
        lbn[i]=(i-1)*sn+1;
        rbn[i]=i*sn;
        for(int k=lbn[i];k<=rbn[i];k++) bn[k] = i;
    }
    if(t*sq<maxm) {
        t++;
        lbn[t]=(t-1)*sn+1;
        rbn[t]=maxm;
        for(int k=lbn[t];k<=rbn[t];k++) bn[k] = t;
    }
    lbn[t+1]=maxm+1;
    rbn[t+1]=inf;
    for(int i=1;i<=n;i++) a[i]=lower_bound(typ+1,typ+maxm+1,a[i])-typ;
    for(int i=1;i<=maxq;i++) 
      if(q[i].num!=2)
        {
            q[i].p=lower_bound(typ+1,typ+maxm+1,q[i].p)-typ;
        }
    for(int i=1;i<=maxc;i++)
      {
          c[i].from=lower_bound(typ+1,typ+maxm+1,c[i].from)-typ;
          c[i].to=lower_bound(typ+1,typ+maxm+1,c[i].to)-typ;
      }
    int l=1,r=0,k=maxc;
    for(int i=1;i<=maxq;i++)
      {
          int ql=q[i].l,qr=q[i].r,qk=q[i].k,op=q[i].num,p=q[i].p;
          while(k<qk)
            {
               ++k;
               if(c[k].p>=l&&c[k].p<=r)
               change(c[k].from,c[k].to);
               a[c[k].p]=c[k].to;
            }
          while(k>qk)
            {
                if(c[k].p>=l&&c[k].p<=r)
                change(c[k].to,c[k].from);
                a[c[k].p]=c[k].from;
                --k;
            }
          while(r<qr)
            {
                ++r;
                b[a[r]]++;
                sum[bn[a[r]]]++;
            }
          while(l>ql)
            {
                --l;
                b[a[l]]++;
                sum[bn[a[l]]]++;
            }
          while(r>qr)
            {
                b[a[r]]--;
                sum[bn[a[r]]]--;
                --r;
            }
          while(l<ql)
            {
                b[a[l]]--;
                sum[bn[a[l]]]--;
                ++l;
            }
          if(op==1) ans[q[i].id]=get_rank(p);
          if(op==2) ans[q[i].id]=get_key(p);
          if(op==4)
            {
                int rank=get_rank(p);
                if(rank>1&&rank<=r-l+2) 
                 {
                  int val=get_key(rank-1);
                  ans[q[i].id]=val;
                 }
                else 
                  {
                      ans[q[i].id]=-inf;
                  }
            }
          if(op==5)
            {
                int rank=get_rank(p+1);
                if(rank>0&&rank<=r-l+1) 
                {
                  int val=get_key(rank);
                  ans[q[i].id]=val; 
                }
                else 
                  {
                      ans[q[i].id]=inf;
                  }
            }
      }
    for(int i=1;i<=maxq;i++) cout<<ans[i]<<endl;
}
2021/6/16 21:35
加载中...