1. 程式人生 > >【刷題】洛谷 P3901 數列找不同

【刷題】洛谷 P3901 數列找不同

math 格式 之前 gist sort put 不同 == sqrt

題目描述

現有數列 \(A_1,A_2,\cdots,A_N\) ,Q 個詢問 \((L_i,R_i)\)\(A_{Li} ,A_{Li+1},\cdots,A_{Ri}\) 是否互不相同

輸入輸出格式

輸入格式:

第1 行,2 個整數 \(N,Q\)

第2 行,N 個整數 \(A_{Li} ,A_{Li+1},\cdots,A_{Ri}\)?

Q 行,每行2 個整數 \(L_i,R_i\)?

輸出格式:

對每個詢問輸出一行,“Yes” 或者“No”

輸入輸出樣例

輸入樣例#1:

4 2
1 2 3 2
1 3
2 4

輸出樣例#1:

Yes
No

說明

? 對於50% 的數據,\(N,Q \le 10^3\)

? 對於100% 的數據, \(1 \le N,Q \le 10^5, 1 \le A_i \le N, 1 \le L_i \le R_i \le N\)

題解

當做莫隊裸題做了,加數和刪數的時候只要判之前或之後是不是一來更改某一段的貢獻
(這題還可以 \(O(n)\) 做,而且很好寫,不過為了寫個模板,就沒去寫了)

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=100000+10; int n,q,A[MAXN],unit,Be[MAXN],cnt[MAXN],sum,ans[MAXN]; struct node{ int l,r,id; inline bool operator < (const node &A) const { return Be[l]==Be[A.l]?r<A.r:l<A.l; }; }; node query[MAXN]; template<typename T> inline void read(T &x) { T data=0
,w=1; char ch=0; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')w=-1,ch=getchar(); while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar(); x=data*w; } template<typename T> inline void write(T x,char ch='\0') { if(x<0)putchar('-'),x=-x; if(x>9)write(x/10); putchar(x%10+'0'); if(ch!='\0')putchar(ch); } template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);} template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);} template<typename T> inline T min(T x,T y){return x<y?x:y;} template<typename T> inline T max(T x,T y){return x>y?x:y;} inline void add(int x) { if((cnt[x]++)==1)sum++; } inline void del(int x) { if((--cnt[x])==1)sum--; } int main() { read(n);read(q); unit=std::sqrt(n); for(register int i=1;i<=n;++i)read(A[i]),Be[i]=i/unit+1; for(register int i=1;i<=q;++i) { read(query[i].l),read(query[i].r); query[i].id=i; } std::sort(query+1,query+q+1); int l=1,r=0; for(register int i=1;i<=q;++i) { while(l<query[i].l)del(A[l++]); while(l>query[i].l)add(A[--l]); while(r<query[i].r)add(A[++r]); while(r>query[i].r)del(A[r--]); ans[query[i].id]=sum; } for(register int i=1;i<=q;++i)puts(ans[i]?"No":"Yes"); return 0; }

【刷題】洛谷 P3901 數列找不同