牛客網暑期ACM多校訓練營(第一場)- J Different Integers (莫隊)
阿新 • • 發佈:2018-07-19
url namespace div struct different operator truct -- eof
題意:裸的莫隊題,每個查詢Li,Ri,返回區間[1,Li]和[Ri,N]區間中不同的數的個數。
分析:正常的離線查詢,是求區間[Li,Ri]中要求的答案,而該題所求答案為外側兩個區間中的答案,那麽cnt[i]維護的東西修改一下即可。對查詢排序的時候,將R較大的排在前面,因為對於所維護的區間,是從兩側往內遞推過來的,這樣才能令不必要的遞推減少。
此外,也有用主席樹和樹狀數組的做法。
#include<bits/stdc++.h> using namespace std; const int maxn =1e5+5; int pos[maxn]; struct Query{ intL,R,id; bool operator <(const Query q) const{ if(pos[L]==pos[q.L]) return R>q.R; return pos[L]<pos[q.L]; } }Q[maxn]; int a[maxn]; int ans[maxn]; int block; int cnt[maxn]; int vis[maxn]; int res; //區間是相反的 void add(int pos) { cnt[a[pos]]++; if(cnt[a[pos]]==1) res++; }void pop(int pos){ cnt[a[pos]]--; if(cnt[a[pos]]==0) res--; } int main() { int n,q; while(scanf("%d%d",&n,&q)==2){ memset(cnt,0,sizeof(cnt)); block =ceil(sqrt(1.0*n)); for(int i=1;i<=n;++i){ scanf("%d",&a[i]); pos[i]= i/block; } for(int i=1;i<=q;++i){ scanf("%d%d",&Q[i].L,&Q[i].R); Q[i].id = i; } sort(Q+1,Q+q+1); int curL=0,curR=n+1; res=0; for(int i=1;i<=q;++i){ //外區間縮 while(curL>Q[i].L) pop(curL--); while(curR<Q[i].R) pop(curR++); //外區間擴 while(curL<Q[i].L) add(++curL); while(curR>Q[i].R) add(--curR); ans[Q[i].id] = res; } for(int i=1;i<=q;++i){ printf("%d\n",ans[i]); } } }
牛客網暑期ACM多校訓練營(第一場)- J Different Integers (莫隊)