1. 程式人生 > >【BZOJ 2821】作詩

【BZOJ 2821】作詩

怎麽辦 如果 lin can con www ++ 強制 const

【題目鏈接】

https://www.lydsy.com/JudgeOnline/problem.php?id=2821

【算法】

如果不強制在線,顯然莫隊是可以解決此題的,那麽,強制在線怎麽辦呢? 分塊

將這個序列分成sqrt(n)段(sqrt表示開方),預處理每段每個數出現的次數與該段“多少數出現了正偶數次”,就可以在線回答詢問了

【代碼】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
const int MAXB = 320
; int i,n,m,c,l,r,x,y,len,block,lastans; int a[MAXN],belong[MAXN],cnt[MAXN],L[MAXB],R[MAXB]; int sum[MAXB][MAXN],ans[MAXB][MAXB]; inline void init() { int i,j,k; len = (int)sqrt(n); block = n / len; for (i = 1; i <= block; i++) { L[i] = (i - 1) * len + 1; R[i]
= i * len; } if (R[block] < n) { block++; L[block] = R[block-1] + 1; R[block] = n; } for (i = 1; i <= n; i++) belong[i] = (i - 1) / len + 1; for (i = 1; i <= n; i++) sum[belong[i]][a[i]]++; for (i = 1; i <= block; i++) { for
(j = 1; j <= c; j++) { sum[i][j] += sum[i-1][j]; } } for (i = 1; i <= block; i++) { for (j = i; j <= block; j++) { ans[i][j] = ans[i][j-1]; for (k = L[j]; k <= R[j]; k++) { cnt[a[k]]++; if (cnt[a[k]] % 2 == 0) ans[i][j]++; else if (cnt[a[k]] > 1) ans[i][j]--; } } for (j = L[i]; j <= n; j++) cnt[a[j]]--; } } inline int query(int l,int r) { int i,ret = 0,t; int p = belong[l], q = belong[r]; if (p == q) { for (i = l; i <= r; i++) { cnt[a[i]]++; if (cnt[a[i]] % 2 == 0) ret++; else if (cnt[a[i]] > 1) ret--; } for (i = l; i <= r; i++) cnt[a[i]]--; return ret; } else { ret = ans[p+1][q-1]; for (i = l; i <= R[p]; i++) { cnt[a[i]]++; t = sum[q-1][a[i]] - sum[p][a[i]] + cnt[a[i]]; if (t % 2 == 0) ret++; else if (t > 1) ret--; } for (i = L[q]; i <= r; i++) { cnt[a[i]]++; t = sum[q-1][a[i]] - sum[p][a[i]] + cnt[a[i]]; if (t % 2 == 0) ret++; else if (t > 1) ret--; } for (i = l; i <= R[p]; i++) cnt[a[i]]--; for (i = L[q]; i <= r; i++) cnt[a[i]]--; return ret; } } int main() { scanf("%d%d%d",&n,&c,&m); for (i = 1; i <= n; i++) scanf("%d",&a[i]); init(); lastans = 0; for (i = 1; i <= m; i++) { scanf("%d%d",&x,&y); l = (x + lastans) % n + 1; r = (y + lastans) % n + 1; if (l > r) swap(l,r); printf("%d\n",lastans = query(l,r)); } return 0; }

【BZOJ 2821】作詩