【洛谷P3901】數列找不同
阿新 • • 發佈:2019-04-04
getch get def 序列 str air += namespace char
題目大意:給定一個長度為 N 的序列,每個點被染了一個顏色。現有 M 個詢問,每個詢問查詢區間 [l,r] 內的點是否顏色都是不同的。
題解:莫隊裸題。
直接維護區間顏色數,用 cnt[] 記錄下區間中顏色出現的次數,用 now 記錄下區間顏色數,查詢時只需比較區間顏色數和區間長度的關系即可。
代碼如下
#include <bits/stdc++.h> #define fi first #define se second #define pb push_back #define mp make_pair #define all(x) x.begin(),x.end() using namespace std; typedef long long ll; typedef pair<int,int> P; const int dx[]={0,1,0,-1}; const int dy[]={1,0,-1,0}; const int mod=1e9+7; const int inf=0x3f3f3f3f; const int maxn=1e5+10; const double eps=1e-6; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll sqr(ll x){return x*x;} inline ll read(){ ll x=0,f=1;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch)); do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch)); return f*x; } /*--------------------------------------------------------*/ int n,m,tot,now,a[maxn],cnt[maxn],ans[maxn]; struct query{int id,bl,l,r;}q[maxn]; bool cmp(const query &x,const query &y){return x.bl==y.bl?x.r<y.r:x.bl<y.bl;} void read_and_parse(){ n=read(),m=read(),tot=sqrt(n); for(int i=1;i<=n;i++)a[i]=read(); for(int i=1;i<=m;i++)q[i].l=read(),q[i].r=read(),q[i].id=i,q[i].bl=(q[i].l-1)/tot+1; sort(q+1,q+m+1,cmp); } inline void update(int pos,int val){ if(val==1){ if(cnt[a[pos]]==0)++now; cnt[a[pos]]+=val; }else{ if(cnt[a[pos]]==1)--now; cnt[a[pos]]+=val; } } void solve(){ for(int i=1,l=0,r=0;i<=m;i++){ while(r<q[i].r)update(r+1,1),++r; while(r>q[i].r)update(r,-1),--r; while(l<q[i].l)update(l,-1),++l; while(l>q[i].l)update(l-1,1),--l; ans[q[i].id]=now==q[i].r-q[i].l+1?1:0; } for(int i=1;i<=m;i++)puts(ans[i]?"Yes":"No"); } int main(){ read_and_parse(); solve(); return 0; }
【洛谷P3901】數列找不同