数列找不同
Posted hrj1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数列找不同相关的知识,希望对你有一定的参考价值。
题目描述
现有数列A_1,A_2,\cdots,A_NA1?,A2?,?,AN?,Q 个询问(L_i,R_i)(Li?,Ri?),A_Li ,A_Li+1,\cdots,A_RiALi?,ALi+1?,?,ARi? 是否互不相同
输入格式
第1 行,2 个整数N,QN,Q
第2 行,N 个整数A_Li ,A_Li+1,\cdots,A_RiALi?,ALi+1?,?,ARi?
Q 行,每行2 个整数L_i,R_iLi?,Ri?
输出格式
对每个询问输出一行,“Yes” 或者“No”
输入输出样例
输入 #1
4 2 1 2 3 2 1 3 2 4
输出 #1
Yes No
说明/提示
• 对于50% 的数据,N,Q \le 10^3N,Q≤103
• 对于100% 的数据,1 \le N,Q \le 10^5, 1 \le A_i \le N, 1 \le L_i \le R_i \le N1≤N,Q≤105,1≤Ai?≤N,1≤Li?≤Ri?≤N
我们想,因为每次查询是离线的,所以我们先给每次的查询排一个序。
排序的方法是
分块。
我们把所有的元素分成多个块(即分块)。分了块跑的会更快。再按照右端点从小到大,左端点块编号相同按右端点从小到大。
#include <cstdio> #include <algorithm> #include <cmath> using namespace std; const int maxn=100010; inline int read() int s=0,w=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) if(ch==‘-‘) w=-1; ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘) s=s*10+ch-‘0‘; ch=getchar(); return s*w; int n,m,hhh,ans=0,kkksc03,kkksc04,cnt[maxn],a[maxn],i; bool anb[maxn]; struct node int l,r,p; q[maxn]; bool cmp(const node x,const node y) return (x.l/hhh)==(y.l/hhh)?x.r<y.r:x.l<y.l; void add(int position) if((++cnt[a[position]])==1) ++ans; void remove(int position) if((--cnt[a[position]])==0) --ans; int main() n=read(); m=read(); hhh=sqrt(n); for(i=1;i<=n;i++) a[i]=read(); for(i=1;i<=m;i++) q[i].l=read(); q[i].r=read(); q[i].p=i; sort(q+1,q+1+m,cmp); for(i=1;i<=m;i++) int L=q[i].l,R=q[i].r; while(kkksc03<L) remove(kkksc03++); while(kkksc03>L) add(--kkksc03); while(kkksc04<R) add(++kkksc04); while(kkksc04>R) remove(kkksc04--); if(ans==(R-L+1)) anb[q[i].p]=1; for(i=1;i<=m;i++) if(anb[i]==1) printf("Yes\n"); else printf("No\n"); return 0;
以上是关于数列找不同的主要内容,如果未能解决你的问题,请参考以下文章