首页 > 代码库 > [BZOJ2821]作诗(Poetize)
[BZOJ2821]作诗(Poetize)
[BZOJ2821]作诗(Poetize)
试题描述
神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗。由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读其中连续的一段[l,r],从这一段中选出一些汉字构成诗。因为SHY喜欢对偶,所以SHY规定最后选出的每个汉字都必须在[l,r]里出现了正偶数次。而且SHY认
为选出的汉字的种类数(两个一样的汉字称为同一种)越多越好(为了拿到更多的素材!)。于是SHY请LYD安排选法。LYD这种傻×当然不会了,于是向你请教……问题简述:N个数,M组询问,每次问[l,r]中有多少个数出现正偶数次。
输入
神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗。由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读其中连续的一段[l,r],从这一段中选出一些汉字构成诗。因为SHY喜欢对偶,所以SHY规定最后选出的每个汉字都必须在[l,r]里出现了正偶数次。而且SHY认为选出的汉字的种类数(两个一样的汉字称为同一种)越多越好(为了拿到更多的素材!)。于是SHY请LYD安排选法。LYD这种傻×当然不会了,于是向你请教……问题简述:N个数,M组询问,每次问[l,r]中有多少个数出现正偶数次。
输出
输出共m行,每行一个整数,第i个数表示SHY第i次能选出的汉字的最多种类数。
输入示例
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; }
[BZOJ2821]作诗(Poetize)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。