• luogu P4688 [Ynoi2016]掉进兔子洞


    bitset优化莫队。

    由于bitset并不能存可重集,所以我们考虑给每种元素在bitset里留 (k) 个位置((k) 为这种元素的个数)。我们只需要在离散化的时候不去重,然后把 (p) 放进bitset中第 (p-cnt_p) 个位置就行了((cnt_p) 为bitset当前存的 (p) 的个数)。

    发现数组开不下,我们把询问分成三段处理就好。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<bitset>
    #include<cmath>
    
    using namespace std;
    
    const int N=100009,M=34000;
    int n,m,a[N],cnt=1,ans1[M],belong[M*3],block,b[N],sum[N];
    bitset <N> now,ans[M];
    struct Question
    {
    	int l,r,id;
    	bool operator < (const Question A)const
    	{
    		if(belong[l]!=belong[A.l])
    			return l<A.l;
    		return (belong[l]&1)?r<A.r:r>A.r;
    	}
    }q[M*3];
    
    int read()
    {
    	int x=0;
    	char c=getchar();
    	while(c<'0'||c>'9')
    		c=getchar();
    	while(c>='0'&&c<='9')
    		x=x*10+c-'0',c=getchar();
    	return x;
    }
    
    void init()
    {
    	n=read(),m=read();
    	for (int i=1;i<=n;i++)
    		a[i]=b[i]=read();
    	sort(b+1,b+1+n);
    	for (int i=1;i<=n;i++)
    		a[i]=upper_bound(b+1,b+1+n,a[i])-b-1;
    	block=(int)sqrt(N);
    	for (int i=1;i<=(M-10)*3;i++)
    		belong[i]=(i-1)/block+1;
    }
    
    void add(int x)
    {
    	now[x-sum[x]]=1;
    	sum[x]++;
    }
    
    void del(int x)
    {
    	sum[x]--;
    	now[x-sum[x]]=0;
    }
    
    void work()
    {
    	int tot=0,all=0;
    	memset(ans1,0,sizeof(ans1));
    	for (int i=1;i<=M-10&&cnt<=m;i++,cnt++,all++)
    		tot++,q[tot].l=read(),q[tot].r=read(),ans1[i]+=q[tot].r-q[tot].l+1,q[tot].id=i,
    		tot++,q[tot].l=read(),q[tot].r=read(),ans1[i]+=q[tot].r-q[tot].l+1,q[tot].id=i,
    		tot++,q[tot].l=read(),q[tot].r=read(),ans1[i]+=q[tot].r-q[tot].l+1,q[tot].id=i;
    	sort(q+1,q+1+tot);
    	memset(sum,0,sizeof(sum));
    	for (int i=1;i<=all;i++)
    		ans[i].set();
    	now.reset();
    	int l=1,r=0;
    	for (int i=1;i<=tot;i++)
    	{
    		while(r<q[i].r) add(a[++r]);
    		while(l>q[i].l) add(a[--l]);
    		while(r>q[i].r) del(a[r--]);
    		while(l<q[i].l) del(a[l++]);
    		ans[q[i].id]&=now;
    	}
    	for (int i=1;i<=all;i++)
    		printf("%d
    ",ans1[i]-ans[i].count()*3);
    	if(cnt<=m)
    		work();
    }
    
    int main()
    {
    	init();
    	work();
    	return 0;
    }
    
    由于博主比较菜,所以有很多东西待学习,大部分文章会持续更新,另外如果有出错或者不周之处,欢迎大家在评论中指出!
  • 相关阅读:
    什么是浮动IP
    How can I detect multiple logins into a Django web application from different locations?
    git add -A使用说明
    理解水平扩展和垂直扩展
    php != 和 !== 的区别
    wireshark:Couldn't run /usr/bin/dumpcap in child process: Permission denied
    Unable to VNC onto Centos server remotely
    systemctl使用说明
    KiB、MiB与KB、MB的区别
    python带setup.py的包的安装
  • 原文地址:https://www.cnblogs.com/With-penguin/p/13321644.html
Copyright © 2020-2023  润新知