【刷題】洛谷 P3901 數列找不同
阿新 • • 發佈:2018-05-21
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 數列找不同