首页 > 代码库 > BZOJ 2821 作诗(Poetize) 分块
BZOJ 2821 作诗(Poetize) 分块
题目大意:给出一段序列,求一段区间内的出现次数为正偶数的数的个数。
思路:50000,分块。主要的事情是处理出来两个数组,一个是整块的答案,空间复杂度为O(√n*√n),还有一个是前缀和每一块的数字出现的次数,空间复杂度O(n*√n)。之后就是暴力了。代码很乱,要根据for来分析时间复杂度。
这个题大概不用读入优化也可以吧,就是空间比较卡。。
(要打时间戳啊!
CODE:
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 320 #define _MAX 100010 using namespace std; inline int getc() { static const int L = 1 << 15; static char buf[L], *S = buf, *T = buf; if (S == T) { T = (S = buf) + fread(buf, 1, L, stdin); if (S == T) return EOF; } return *S++; } inline int getint() { int c; while(!isdigit(c = getc()) && c != '-'); bool sign = c == '-'; int tmp = sign ? 0 : c - '0'; while(isdigit(c = getc())) tmp = (tmp << 1) + (tmp << 3) + c - '0'; return sign ? -tmp : tmp; } int cnt,cols,asks; int block_size,blocks; int src[_MAX],belong[_MAX],begin[_MAX]; int ans_block[MAX][MAX]; int cnt_block[MAX][_MAX]; int temp[_MAX],v[_MAX],T; int stack[_MAX],top; int main() { cin >> cnt >> cols >> asks; block_size = sqrt(cnt); for(int i = 1; i <= cnt; ++i) { src[i] = getint(); //scanf("%d",&src[i]); belong[i] = i / block_size + 1; if(!begin[belong[i]]) begin[belong[i]] = i; ++cnt_block[belong[i]][src[i]]; } blocks = belong[cnt]; //Making cnt_block[][](preSum for(int i = 2; i <= blocks; ++i) for(int j = 1; j <= cols; ++j) cnt_block[i][j] += cnt_block[i - 1][j]; //Making ans_block[][]; int now; for(int i = 1; i <= blocks; ++i) { now = 0; ++T; for(int j = begin[i]; j <= cnt + 1; ++j) { if(belong[j] != belong[j - 1]) ans_block[i][belong[j - 1]] = now; if(v[src[j]] != T) v[src[j]] = T,temp[src[j]] = 0; if(temp[src[j]] > 0) { if(temp[src[j]]&1) ++now; else --now; } ++temp[src[j]]; } } //Asking int last_ans = 0; for(int x,y,i = 1; i <= asks; ++i) { x = getint(),y = getint(); //scanf("%d%d",&x,&y); x = (x + last_ans) % cnt + 1; y = (y + last_ans) % cnt + 1; if(x > y) swap(x,y); int st = belong[x] + 1,ed = belong[y] - 1,ans = 0; ++T; if(st > ed) { for(int j = x; j <= y; ++j) { if(v[src[j]] != T) v[src[j]] = T,temp[src[j]] = 0; if(temp[src[j]] > 0) { if(temp[src[j]]&1) ++ans; else --ans; } ++temp[src[j]]; } printf("%d\n",last_ans = ans); continue; } ans = ans_block[st][ed]; top = 0; for(int k = x; belong[k] == belong[x]; ++k) stack[++top] = src[k]; for(int k = y; belong[k] == belong[y]; --k) stack[++top] = src[k]; sort(stack + 1,stack + top + 1); stack[top + 1] = 0; int num = 0; for(int j = 1; j <= top + 1; ++j) { ++num; if(stack[j] != stack[j + 1]) { int temp = cnt_block[ed][stack[j]] - cnt_block[st - 1][stack[j]]; if(!temp) ans += !(num&1); else if(num&1) { if(temp&1) ++ans; else --ans; } num = 0; } } printf("%d\n",last_ans = ans); } return 0; }
BZOJ 2821 作诗(Poetize) 分块
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。