1. 程式人生 > >Army Creation CodeForces - 813E (水題)

Army Creation CodeForces - 813E (水題)

題意: 給定序列, 每次詢問一個區間[l,r], 問[l,r]中最多能選多少個數且每種數字不超過k

 

 

相當於加強版 HH的項鍊, 對於一個數t, 主席樹維護上k次出現的位置pre[t], 每次查詢相當於求區間內pre<左端點的總數

 

#include <iostream>
#include <queue>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define mid ((l+r)>>1)
using namespace std;
const int N = 1e5+10
, INF = 0x3f3f3f3f; int tot, n, m, k; int cnt[N], rt[N]; deque<int> pre[N]; struct _ {int l,r,sum;} tr[N<<5]; void ins(int &o, int l, int r, int x) { ++tot,tr[tot]=tr[o],o=tot,++tr[o].sum; if (l==r) return; if (mid>=x) ins(tr[o].l,l,mid,x); else ins(tr[o].r,mid+1,r,x); }
int query(int u, int v, int l, int r, int x) { if (l==r) return 0; if (mid>=x) return query(tr[u].l,tr[v].l,l,mid,x); return tr[tr[v].l].sum-tr[tr[u].l].sum+query(tr[u].r,tr[v].r,mid+1,r,x); } int main() { scanf("%d%d", &n, &k); REP(i,1,n) { int t, x=0; scanf(
"%d", &t); rt[i] = rt[i-1]; if (pre[t].size()==k) { x = pre[t].front(); pre[t].pop_front(); } ins(rt[i],0,n,x); pre[t].push_back(i); } scanf("%d", &m); int ans = 0; REP(i,1,m) { int l, r; scanf("%d%d", &l, &r); l = (l+ans)%n+1; r = (r+ans)%n+1; if (l>r) swap(l,r); printf("%d\n", ans=query(rt[l-1],rt[r],0,n,l)); } }