传送门

Description

一个长为 n 的序列 a。

有 m 个询问,每次询问三个区间,把三个区间中同时出现的数一个一个删掉,问最后三个区间剩下的数的个数和,询问独立。

注意这里删掉指的是一个一个删,不是把等于这个值的数直接删完,

比如三个区间是 [1,2,2,3,3,3,3] , [1,2,2,3,3,3,3] 与 [1,1,2,3,3],就一起扔掉了 1 个 1,1 个 2,2 个 3。

Solution

弱化版是luoguP3674,这里放上它的题解 戳我

要找相同的元素就是集合求交集,莫队+bitset即可

可是这道题是要算上重复的元素的,很简单,离散化的时候给每个数留下相应的空位就行了

即每个数的离散值等于小于它的数个数+1.

几个例子:

我们把序列3 3 5 5 6 7 7,离散化成1 1 3 3 5 6 6,而不是1 1 2 2 3 4 4

那么,我们在加入数的时候,把它加到“它的离散值+它出现的次数-1”这个位置上

那么求交就是now.count()

还有一个问题,维护\(100000*100000\)的bitset!虽然看上去不太可能,但其实上我们分成3次莫队就行了

Code 

#include<bits/stdc++.h>
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
} #define MN 100005
int n,m,a[MN],T,nums[MN];
std::bitset<MN> now;
std::bitset<MN> quer[33343];
struct ques{
int l,r,id,pl;
bool operator <(const ques&o)const{return (pl^o.pl)?(pl<o.pl):((pl&1)?r<o.r:r>o.r);}
}q[MN+33343];
int num[MN],len[MN]; inline void solve(int L,int R)
{
if(L>R) return;
register int tt=0,i;
for(i=1;i<=R-L+1;++i)
{
quer[i].set();
q[++tt].l=read(),q[tt].r=read();q[tt].pl=(q[tt].l-1)/T+1;q[tt].id=i;len[i] =q[tt].r-q[tt].l+1;
q[++tt].l=read(),q[tt].r=read();q[tt].pl=(q[tt].l-1)/T+1;q[tt].id=i;len[i]+=q[tt].r-q[tt].l+1;
q[++tt].l=read(),q[tt].r=read();q[tt].pl=(q[tt].l-1)/T+1;q[tt].id=i;len[i]+=q[tt].r-q[tt].l+1;
}
std::sort(q+1,q+tt+1);
register int l=1,r=0;now.reset();
memset(num,0,sizeof num); for(i=1;i<=tt;++i)
{
for(;r<q[i].r;++r) num[a[r+1]]++,now[a[r+1]+num[a[r+1]]-1]=1;
for(;l>q[i].l;--l) num[a[l-1]]++,now[a[l-1]+num[a[l-1]]-1]=1;
for(;r>q[i].r;--r) now[a[r]+num[a[r]]-1]=0,--num[a[r]];
for(;l<q[i].l;++l) now[a[l]+num[a[l]]-1]=0,--num[a[l]];
quer[q[i].id]&=now;
}
for(i=1;i<=R-L+1;++i) printf("%d\n",len[i]-3*quer[i].count());
} int main()
{
n=read();m=read();
register int i;T=ceil(sqrt((double)n));
for(i=1;i<=n;++i) nums[i]=a[i]=read();
std::sort(nums+1,nums+n+1);
for(i=1;i<=n;++i) a[i]=std::lower_bound(nums+1,nums+n+1,a[i])-nums; int N1=m/3+1,N2=2*N1;
solve(1,min(N1,m));solve(min(N1,m)+1,min(N2,m));solve(min(N2,m)+1,m);
return 0;
}

Blog来自PaperCloud,未经允许,请勿转载,TKS!

最新文章

  1. 【学习篇:他山之石,把玉攻】Ajax请求安全性讨论
  2. saiku缓存整理
  3. VMware中CentOS设置静态IP
  4. MVC中使用AuthorizeAttribute注意事项
  5. 导入excel数据
  6. 关于RGB转换YUV的探讨与实现
  7. 分享red hat linux 6上安装oracle11g时遇到的gcc: error trying to exec &#39;cc1&#39;: execvp: No such file or directory的问题处理过程
  8. 牛腩新闻公布系统--学习Web的小技巧汇总
  9. mysql 截取替换某个字符串
  10. Linux下用gSOAP开发Web Service服务端和客户端程序
  11. bcdboot(引导修复工具) 命令行工具使用方法
  12. android-基础编程-ScrollView
  13. #1075 : 开锁魔法III
  14. Top PG Clustering HA Solutions for PostgreSQL
  15. 图像检索:一维直方图+欧几里得距离+flann+KNN
  16. 贪吃蛇小游戏-----C语言实现
  17. 如何利用启明星Portal门户系统的Page模块构建工作流表单
  18. linux 内核调试之关键函数名记要
  19. DS博客作业01--日期抽象数据类型
  20. 04_Docker入门(下)之docker镜像和仓库的使用

热门文章

  1. NoSql 使用小结
  2. 多核cpu关闭、开启核心
  3. orangepi香橙派安装VNC Viewer远程桌面
  4. centos7 配置yum源
  5. C++——异常处理
  6. 【搜索-剪枝-偏难】PAT-天梯赛-L3-015. 球队“食物链”
  7. linux下环境管理anaconda3
  8. 8 loader - 配置处理css样式表的第三方loader
  9. python----装饰器(几种常见方式的使用与理解)
  10. SQL 学习指南-数据库使用