标签:space 答案 nbsp center targe ppc mem tar 连续
[BZOJ2821]作诗(Poetize)
试题描述
输入
输出
输入示例
5 3 5 1 2 2 3 1 0 4 1 2 2 2 2 3 3 5
输出示例
2 0 0 0 1
数据规模及约定
对于100%的数据,1<=n,c,m<=10^5
题解
分块,统计出 f[i][j] 表示第 i 个块到第 j 个块中出现正偶次的数有多少个。对于一个询问 [ql, qr],我们搞出那一段连续整块的答案,然后对于首尾零散的部分我们依次把所有出现的颜色统计一下它在整块那一段连续整块中出现次数的奇偶性和它在 [ql, qr] 中出现次数的奇偶性加加减减调整答案就好了。
这题做法其实和区间众数很类似。
这题块的大小要开小点(sqrt(n / log2(n) )),否则会 T 得很惨。。。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <algorithm> #include <vector> #include <cmath> using namespace std; const int BufferSize = 1 << 16; char buffer[BufferSize], *Head, *Tail; inline char Getchar() { if(Head == Tail) { int l = fread(buffer, 1, BufferSize, stdin); Tail = (Head = buffer) + l; } return *Head++; } int read() { int x = 0, f = 1; char c = Getchar(); while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = Getchar(); } while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = Getchar(); } return x * f; } #define maxn 100010 #define maxbl 2010 int n, A[maxn], tot[maxn]; int cb, st[maxbl], en[maxbl], even[maxbl][maxbl], blid[maxn]; vector <int> pos[maxn]; int calc(int l, int r, int col) { if(l > r) return 0; return upper_bound(pos[col].begin(), pos[col].end(), r) - lower_bound(pos[col].begin(), pos[col].end(), l); } int appcol[maxn], capp, clo[maxn]; int query(int ql, int qr, int tag) { if(blid[ql] == blid[qr]) { int tmp = 0; for(int i = ql; i <= qr; i++) { if(clo[A[i]] != tag) clo[A[i]] = tag, tot[A[i]] = 0; tot[A[i]]++; if((tot[A[i]] & 1) && tot[A[i]] > 1) tmp--; if(!(tot[A[i]] & 1)) tmp++; } return tmp; } int bl = blid[ql], br = blid[qr], tmp = even[bl+1][br-1]; capp = 0; for(int i = ql; i <= en[bl]; i++) { if(clo[A[i]] != tag) clo[A[i]] = tag, tot[A[i]] = 0; if(!tot[A[i]]) appcol[++capp] = A[i]; tot[A[i]] = 1; } for(int i = st[br]; i <= qr; i++) { if(clo[A[i]] != tag) clo[A[i]] = tag, tot[A[i]] = 0; if(!tot[A[i]]) appcol[++capp] = A[i]; tot[A[i]] = 1; } for(int i = 1; i <= capp; i++) { int appt = calc(ql, qr, appcol[i]), appt_bl = calc(st[bl+1], en[br-1], appcol[i]); if(!(appt & 1) && ((appt_bl & 1) || !appt_bl)) tmp++; if((appt & 1) && (!(appt_bl & 1) && appt_bl)) tmp--; } return tmp; } int main() { n = read(); int C = read(), q = read(); for(int i = 1; i <= n; i++) A[i] = read(); int m = 50; for(int i = 1; i <= n; i++) { int bl = (i - 1) / m + 1; cb = max(cb, bl); blid[i] = bl; if(!st[bl]) st[bl] = i; en[bl] = i; pos[A[i]].push_back(i); } for(int i = 1; i <= cb; i++) { memset(tot, 0, sizeof(tot)); int tmp = 0; for(int j = st[i]; j <= n; j++) { tot[A[j]]++; if((tot[A[j]] & 1) && tot[A[j]] > 1) tmp--; if(!(tot[A[j]] & 1)) tmp++; if(j == n || blid[j] != blid[j+1]) even[i][blid[j]] = tmp; } } int lstans = 0; while(q--) { int l = (read() + lstans) % n + 1, r = (read() + lstans) % n + 1; if(l > r) swap(l, r); printf("%d\n", lstans = query(l, r, q + 1)); } return 0; }
标签:space 答案 nbsp center targe ppc mem tar 连续
原文地址:http://www.cnblogs.com/xiao-ju-ruo-xjr/p/6789208.html