【题解】Luogu P3901 数列找不同
2024-10-18 23:33:10
我博客中对莫队的详细介绍
原题传送门
不错的莫队练手题
块数就直接取sqrt(n)
对所有询问进行排序
排序第一关键词:l所在第几块,第二关键词:r的位置
考虑Ai不大,暴力开数组
add时如果加之后的数量是1
总数就加1
del时如果减之后的数量是0
总数就减1
每次比较总数和该次查询区间的长度
相等的话就把 ans[q[i].id]设为真
最后如果ans[i]为真就输出Yes,否则输出No
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define N 100005
using namespace std;
inline int read()
{
register 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;
}
int v[N],blocksize=0;
struct query{
int l,r,id,bl;
}q[N];
int sum[N];
bool ans[N];
int cnt=0;
inline void add(register int x)
{
if(++sum[v[x]]==1)
++cnt;
}
inline void del(register int x)
{
if(--sum[v[x]]==0)
--cnt;
}
inline bool cmp(register query a,register query b)
{
return a.bl==b.bl?a.r<b.r:a.bl<b.bl;
}
int main()
{
memset(sum,0,sizeof(sum));
int n=read(),m=read();
blocksize=sqrt(n);
for(register int i=1;i<=n;++i)
v[i]=read();
for(register int i=1;i<=m;++i)
{
int l=read(),r=read();
q[i]=(query){l,r,i,(l-1)/blocksize+1};
}
sort(q+1,q+m+1,cmp);
int l=1,r=0;
for(register int i=1;i<=m;++i)
{
int ll=q[i].l,rr=q[i].r;
while(l<ll)
del(l++);
while(l>ll)
add(--l);
while(r<rr)
add(++r);
while(r>rr)
del(r--);
ans[q[i].id]=(cnt==rr-ll+1)?1:0;
}
for(register int i=1;i<=m;++i)
if(ans[i])
puts("Yes");
else
puts("No");
return 0;
}
最新文章
- [LeetCode] Best Meeting Point 最佳开会地点
- 【原创】开源Math.NET基础数学类库使用(09)相关数论函数使用
- js限制输入框只能输入数字
- 线程操作UI界面的方法
- Java Servlet(六):HttpServlet实现原理(jdk7+tomcat7+eclipse)
- app测试与web测试的区别
- Mac OS使用ll、la、l等ls的别名命令
- JS中的集中页面跳转的方法
- grunt自动化工具
- Lua基础之Function
- ORCAL
- 7——使用TextView实现跑马灯
- JavaScript学习笔记2-数组对象
- MongoDB文档基本操作
- javascript篇-----数据类型
- linux下使用自带mail发送邮件(超简单)
- 【BZOJ1084】最大子矩阵(动态规划)
- springboot多模块项目下,子模块调用报错:程序包xxxxx不存在
- CLR Via 第一 章 知识点整理(2)程序集和CLR的启动
- SQL年月日格式化