zoukankan      html  css  js  c++  java
  • luogu P4688 [Ynoi2016]掉进兔子洞

    luogu

    我们要求的答案应该是三个区间长度(-3*)在三个区间中都出现过的数个数

    先考虑数列中没有相同的数怎么做,那就是对三个区间求交,然后交集大小就是要求的那个个数.现在有相同的数,考虑给区间中的数安排位置,即区间中如果出现了多个相同的数(x),那么就把第一个(x)放在(x)这种数要放的第一个位置,把第二个(x)放在第二个对应位置,依次类推.具体的,我们用桶维护区间内所有数的出现次数,然后给每种数安排一个初始下标(ps_x),使得后面过程中放数不会重叠,如果数(x)出现了(c)次,那么就把另一个数组内([ps_x,ps_x+c-1])这些位置记为1.那如果把一个询问的三个区间对应的状态数组取交,交集大小即为我们要的都出现过的数个数

    求交集显然可以套bitset,然后询问若干区间信息再套个莫队,每次某个询问把三个区间的bitset并在另一个对应的bitset就行了.注意空间可能一次开不下,所以要把询问分成若干组去跑

    #include<bits/stdc++.h>
    #define LL long long
    #define LLL __int128
    #define db double
    
    using namespace std;
    const int N=1e5+10,qsz=570;
    int rd()
    {
    	int x=0,w=1;char ch=0;
    	while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    	return x*w;
    }
    int n,q,t,bl[N],a[N],b[N],cn[N],zq[N>>2],an[N>>2];
    bitset<N> bb[N>>2],nb;
    struct QR
    {
    	int l,r,i;
    	bool operator < (const QR &bb) const {return bl[l]!=bl[bb.l]?bl[l]<bl[bb.l]:r<bb.r;}
    }qq[N];
    
    int main()
    {
    	n=rd(),q=rd();
    	for(int i=1;i<=n;++i) bl[i]=i/qsz;
    	for(int i=1;i<=n;++i) a[i]=b[i]=rd();
    	sort(b+1,b+n+1),t=unique(b+1,b+n+1)-b-1;
    	for(int i=1;i<=n;++i)
    	{
    		a[i]=lower_bound(b+1,b+t+1,a[i])-b;
    		++cn[a[i]+1];
    	}
    	for(int i=3;i<=t;++i) cn[i]+=cn[i-1];
    	for(int i=1,j=25000;i<=q;i+=25000,j+=25000)
    	{
    		j=min(j,q);
    		int tq=0;
    		for(int k=i,o=1;k<=j;++k,++o)
    		{
    			zq[o]=an[o]=0;
    			int l=rd(),r=rd();
    			an[o]+=r-l+1,qq[++tq]=(QR){l,r,o};
    			l=rd(),r=rd();
    			an[o]+=r-l+1,qq[++tq]=(QR){l,r,o};
    			l=rd(),r=rd();
    			an[o]+=r-l+1,qq[++tq]=(QR){l,r,o};
    		}
    		sort(qq+1,qq+tq+1);
    		qq[++tq]=(QR){n+1,n,0};
    		for(int k=1,l=1,r=0;k<=tq;++k)
    		{
    			while(r<qq[k].r){++r,++cn[a[r]],nb[cn[a[r]]]=1;}
    			while(r>qq[k].r){nb[cn[a[r]]]=0,--cn[a[r]],--r;}
    			while(l<qq[k].l){nb[cn[a[l]]]=0,--cn[a[l]],++l;}
    			while(l>qq[k].l){--l,++cn[a[l]],nb[cn[a[l]]]=1;}
    			if(!qq[k].i) continue;
    			if(!zq[qq[k].i]) bb[qq[k].i]=nb;
    			else bb[qq[k].i]&=nb;
    			++zq[qq[k].i];
    		}
    		for(int k=i,o=1;k<=j;++k,++o) printf("%d
    ",an[o]-3*(int)bb[o].count());
    	}
    	return 0;
    }
    
  • 相关阅读:
    【Silverlight】Bing Maps系列文章汇总
    《MEF程序设计指南》博文汇总
    Flash中各种图形的绘制
    Bing Maps开发扩展二:基于Oracle Spatial的空间数据分析
    Bing Maps开发扩展三:Bing Maps中渲染ESRI SHP空间数据
    Spring Cloud Gateway
    Spring Cloud Gateway 整合 nacos
    Spring Cloud Gateway 断言(Predicate) (hoxton 版本)
    Python和Node.js支持尾递归吗?
    用OpenCv来做人脸识别
  • 原文地址:https://www.cnblogs.com/smyjr/p/11745250.html
Copyright © 2011-2022 走看看