Educational Codeforces Round 22 E. Army Creation 主席樹 或 分塊
As you might remember from our previous rounds, Vova really likes computer games. Now he is playing a strategy game known as Rage of Empires.
In the game Vova can hire n different warriors; ith warrior has the type ai. Vova wants to create a balanced army hiring some subset of warriors. An army is called balanced if for each type of warrior present in the game there are not more than k
To make things more complicated, Vova has to consider q different plans of creating his army. ith plan allows him to hire only warriors whose numbers are not less than li and not greater than ri.
Help Vova to determine the largest size of a balanced army for each plan.
Be aware that the plans are given in a modified way. See input section for details.
InputThe first line contains two integers n and k (1 ≤ n, k ≤ 100000).
The second line contains n integers a1, a2, ... an (1 ≤ ai ≤ 100000).
The third line contains one integer q
Then q lines follow. ith line contains two numbers xi and yi which represent ith plan (1 ≤ xi, yi ≤ n).
You have to keep track of the answer to the last plan (let‘s call it last). In the beginning last = 0. Then to restore values of li and ri for the ith plan, you have to do the following:
- li = ((xi + last) mod n) + 1;
- ri = ((yi + last) mod n) + 1;
- If li > ri, swap li and ri.
Print q numbers. ith number must be equal to the maximum size of a balanced army when considering ith plan.
Example input6 2output
1 1 1 2 2 2
5
1 6
4 3
1 1
2 6
2 6
2Note
4
1
3
2
In the first example the real plans are:
- 1 2
- 1 6
- 6 6
- 2 4
- 4 6
題意:
給出長度為n的數組和k
要求在線詢問區間[l, r]權值, 權值定義為對於所有不同元素a[i]在區間出現的次數總和;
如果x出現次數>k, 那麽按k算。
題解:
k = 1時就是 求區間不同數個數了
k大一點,那麽往前數第k個以前出現的相同的數就是多余的了;
插好,主席樹求一求
這題還可以分快寫
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; const long long INF = 1e18+1LL; const double Pi = acos(-1.0); const int N = 4e6+10, M = 1e3+20, mod = 1e9+7,inf = 2e9; int n,k,a[N]; vector<int > G[N]; int l[N],r[N],v[N],sz; void update(int x,int &y,int ll,int rr,int k,int c) { y = ++sz; v[y] = v[x] + c; r[y] = r[x]; l[y] = l[x]; if(ll == rr) return ; if(k <= mid) update(l[x],l[y],ll,mid,k,c); else update(r[x],r[y],mid+1,rr,k,c); } int query(int x,int ll,int rr,int s,int t) { if(s <= ll && rr <= t) return v[x]; int ret = 0; if(s <= mid) ret += query(l[x],ll,mid,s,t); if(t > mid) ret += query(r[x],mid+1,rr,s,t); return ret; } int b[N],root[N]; int main() { scanf("%d%d",&n,&k); for(int i = 1; i <= n; ++i)scanf("%d",&a[i]); for(int i = 1; i <= n; ++i)G[a[i]].push_back(i); for(int i = 1; i <= 100000; ++i) { if(G[i].size() <= k) continue; for(int j = k; j < G[i].size(); ++j) { b[G[i][j]] = G[i][j-k]; } } for(int i = 1; i <= n; ++i) { int xx = 0; if(b[i]) update(root[i-1],xx,1,n,b[i],-1), update(xx,root[i],1,n,i,1); else update(root[i-1],root[i],1,n,i,1); } int q,last = 0; scanf("%d",&q); while(q--) { int x,y; scanf("%d%d",&x,&y); int L = (x + last)%n + 1; int R = (y + last)%n + 1; if(L > R) swap(L,R); last = query(root[R],1,n,L,R); printf("%d\n",last); } return 0; }
Educational Codeforces Round 22 E. Army Creation 主席樹 或 分塊