• Ynoi2016 掉进兔子洞


    Link
    首先容斥转化为求删掉的数的个数。
    考虑如果所选的区间内不存在重数怎么做。
    先离散化。
    然后我们需要对每个询问求其删掉的数。
    把每个询问拆成3个区间跑莫队。
    跑的时候用bitset记录当前区间内有哪些数就行了。
    考虑如何处理重数的问题。
    (i)在序列中出现的次数为(cnt_i)
    显然(sum cnt=n)。并且任意区间中(i)出现的次数不会超过(cnt_i)
    对于没有重数的bitset,(i)占据的是(i)这个位置。
    而现在有重数了,我们就让(i)占据(sumlimits_{j=1}^{i-1}cnt_j+1)(sumlimits_{j=1}^icnt_j)的位置。
    同时我们实时维护一个(pos_i)表示下一个(i)占据的位置。
    具体而言,第(j)(i)将占据(sumlimits_{k=1}^{i-1}cnt_k+j)的位置。
    因为我们给每个(i)都分配了恰好(cnt_i)的位置。
    所以这个bitset的大小依旧是(n),并且不同的数不可能占据相同的位置。
    而且对于(i),它一定先占据能占据的前面的位置。
    所以这样做一定是正确的。
    然后你就会发现你开不下这么多bitset。
    所以我们把询问拆成(3-4)组跑就没问题了。
    实现上有一些小trick。

    #include<bits/stdc++.h>
    #define mp make_pair
    #define P pair<int,int>
    #define fir first
    #define sec second
    using namespace std;
    namespace IO
    {
        char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[15],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
        char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
        void Flush(){fwrite(obuf,1,oS-obuf,stdout),oS=obuf;}
        void Put(char x){*oS++=x;if(oS==oT)Flush();}
        int read(){int x=0;char ch=Get();while(ch>57||ch<48)ch=Get();while(ch>=48&&ch<=57)x=x*10+(ch^48),ch=Get();return x;}
        void write(int x){int top=0;if(!x)Put('0');while(x)st[++top]=(x%10)+48,x/=10;while(top)Put(st[top--]);Put('
    ');}
    }
    using namespace IO;
    const int N=100007,M=25007,S=300;
    int a[N],bel[N],pos[N],sum[M],vis[M];
    P t[N];
    bitset<N>s[M],del;
    struct node{int l,r,id;}q[M*3];
    int operator<(node a,node b){return bel[a.l]^bel[b.l]? a.l<b.l:a.r<b.r;}
    void solve(int m)
    {
        memset(vis,0,sizeof vis),memset(sum,0,sizeof sum);
        int tot=0,i,l,r,j;
        for(i=1;i<=m;++i) for(j=0;j<=2;++j) l=read(),r=read(),q[++tot]=(node){l,r+1,i},sum[i]+=r+1-l;
        sort(q+1,q+tot+1),q[++tot]=(node){1,1,0};
        for(del.reset(),i=l=r=1;i<=tot;++i)
        {
    	while(r<q[i].r) del[++pos[a[r]]]=1,++r;
    	while(l>q[i].l) --l,del[++pos[a[l]]]=1;
    	while(r>q[i].r) --r,del[pos[a[r]]--]=0;
    	while(l<q[i].l) del[pos[a[l]]--]=0,++l;
    	vis[q[i].id]? s[q[i].id]&=del:(vis[q[i].id]=1,s[q[i].id]=del);
        }
        for(i=1;i<=m;++i) write(sum[i]-s[i].count()*3);
    }
    int main()
    {
        int i,k,n=read(),m=read();
        for(i=1;i<=n;++i) a[i]=read(),t[i]=mp(a[i],i),bel[i]=i/S;
        sort(t+1,t+n+1);
        for(i=1,k=0;i<=n;++i) a[t[i].sec]=t[i].fir==t[i-1].fir? k:++k;
        for(i=1;i<=n;++i) if(t[i].fir^t[i-1].fir) pos[a[t[i].sec]]=i;
        while(m) m<=25000? (solve(m),m=0):(solve(25000),m-=25000);
        return Flush(),0;
    }
    
  • 相关阅读:
    spring boot 中@Mapper和@Repository的区别
    yarn和npm的对比以及yarn的使用
    vue环境搭建
    小白的springboot之路(六)、跨域解决方案CORS
    DWR3.0框架入门(1) —— 实现ajax
    DWR3.0框架入门(3) —— ScriptSession的维护及优化
    DWR3.0框架入门(2) —— DWR的服务器推送
    Freemarker入门案例
    dom4j生成和解析xml文件
    struts2拦截器-自定义拦截器,放行某些方法(web.xml配置)
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11913516.html
Copyright © 2020-2023  润新知