【bzoj 2821】 作诗 题意&题解&代码(C++)
来源:互联网 发布:格式化数据恢复 编辑:程序博客网 时间:2024/06/13 06:23
题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=2821
权限题,附题意:
题解:
分块题,他要求在线处理区间问题,很明显是为了卡莫队这种神奇算法,首先将序列分块,按 sqrt(n) (即根号n)分块,然后预处理出一个数组 f[i][j] 表示从第 i 块到第 j 块内,满足题意的答案,还要处理出另一个数组 cnt[i][j] 表示前 i 块中数字 j 出现了多少次,(不要担心数组太大开不下,三千两百万它还真就是存下了,o.o!),这样的话当询问区间 (i,j)时,我们利用 f[i][j] 通过各种判断首先将包含在这个区间里的块的答案统计出来,再利用 cnt[i][j] 将两头或是一头没有达到一整快的部分暴力的统计,一边统计一边修改已经得到的答案即可,时限还是够的。
注意题中一个特别坑的地方,
他特别心机的的在mod与n+1 之间加了一个空格,让大家以为是mod(n+1)实际上却是(mod n)+1。。2333
代码
#include<iostream>#include<algorithm>#include<stdio.h>#include<string.h>#include<math.h>#define maxn (100005)#define maxs (320)using namespace std;int vis[maxn],ans,L,R,len,n,num,c,m,sq[maxn],f[maxs][maxs],cnt[maxs][maxn],a[maxn],st[maxs],tmp[maxn];void solve(int l,int r)//计算 l,r{ if (sq[l]==sq[r] || sq[l]+1==sq[r]) { for (int i=l;i<=r;i++) { vis[a[i]]++; if (vis[a[i]]%2==0) ans++; else if (vis[a[i]]!=1) ans--; } for (int i=l;i<=r;i++) vis[a[i]]=0; return ; } if (l==st[sq[l]] && r==st[sq[r]+1]-1) { ans=f[sq[l]][sq[r]]; return ; } else if (l==st[sq[l]]) { ans=f[sq[l]][sq[r]-1]; for (int i=st[sq[r]];i<=r;i++) vis[a[i]]=cnt[sq[r]-1][a[i]]-cnt[sq[l]-1][a[i]]; for (int i=st[sq[r]];i<=r;i++) { vis[a[i]]++; if (vis[a[i]]%2==0) ans++; else if (vis[a[i]]!=1) ans--; } for (int i=st[sq[r]];i<=r;i++) vis[a[i]]=0; return ; } else if (r==st[sq[r]+1]-1) { ans=f[sq[l]+1][sq[r]]; for (int i=l;i<st[sq[l]+1];i++) vis[a[i]]=cnt[sq[r]][a[i]]-cnt[sq[l]][a[i]]; for (int i=l;i<st[sq[l]+1];i++) { vis[a[i]]++; if (vis[a[i]]%2==0) ans++; else if (vis[a[i]]!=1) ans--; } for (int i=l;i<st[sq[l]+1];i++) vis[a[i]]=0; return ; } else { int x=sq[l]+1; int y=sq[r]-1; ans=f[x][y]; for (int i=l;i<st[x];i++) vis[a[i]]=cnt[y][a[i]]-cnt[x-1][a[i]]; for (int i=st[y+1];i<=r;i++) vis[a[i]]=cnt[y][a[i]]-cnt[x-1][a[i]]; for (int i=l;i<st[x];i++) { vis[a[i]]++; if (vis[a[i]]%2==0) ans++; else if (vis[a[i]]!=1) ans--; } for (int i=st[y+1];i<=r;i++) { vis[a[i]]++; if (vis[a[i]]%2==0) ans++; else if (vis[a[i]]!=1) ans--; } for (int i=l;i<st[x];i++) vis[a[i]]=0; for (int i=st[y+1];i<=r;i++) vis[a[i]]=0; return ; }}int main(){ scanf("%d%d%d",&n,&c,&m); len=sqrt(n); for (int i=1;i<=n;i++) { scanf("%d",&a[i]); sq[i]=(i-1)/len+1; cnt[sq[i]][a[i]]++; if (sq[i]!=sq[i-1]) st[sq[i]]=i; } num=sq[n]; for (int i=1;i<=num;i++) for (int j=1;j<=c;j++) cnt[i][j]+=cnt[i-1][j]; //预处理 cnt数组 for (int i=1;i<=num;i++) { int tans=0; for (int j=1;j<=c;j++) tmp[j]=0; for (int j=st[i];j<=n;j++) { tmp[a[j]]++; if (tmp[a[j]]%2==0) tans++; else if (tmp[a[j]]!=1) tans--; f[i][sq[j]]=tans; } }//预处理 f 数组 ans=0; for (int i=1;i<=m;i++) { scanf("%d%d",&L,&R); L=(L+ans)%n+1; R=(R+ans)%n+1; ans=0; if (L>R) swap(L,R); solve(L,R); printf("%d\n",ans); }}
不得不说,csdn的博客编辑最近好像十分的恶心。。。
0 0
- 【bzoj 2821】 作诗 题意&题解&代码(C++)
- 【bzoj 2433】【NOI 2011】 智能车比赛 题意&题解&代码(C++)
- BZOJ 2821 作诗 (分块)
- POJ 2828 Buy Tickets 题意&题解&代码(c++)
- 【POJ 2104】K-th Number 题意&题解&代码(c++)
- 【POJ 1451】T9 中文题意&题解&代码(c++)
- 【POJ 3461】Oulipo 中文题意&题解&代码(C++)
- 【hdu 2222】Keywords Search 中文题意&题解&代码(C++)
- 【POJ2406】Power Strings 中文题意&题解&代码(C++)
- 【POJ 3630】Phone List 中文题意&题解&代码(C++)
- 【POJ 2296】 Ring 中文题意&题解&代码(C++)
- 【POJ 2778】DNA Sequence 中文题意&题解&代码(C++)
- 【hdu 5635】LCP Array 中文题意&题解&代码(C++)
- 【hdu 5636】Shortest Path 中文题意&题解&代码(C++)
- 【hdu 5637】Transform 中文题意&题解&代码(C++)
- 【hdu 5638】Toposort 中文题意&题解&代码(C++)
- 【poj 1321】 棋盘问题 题解&题意&代码(C++)
- 【poj 3009】Curling 2.0 中文题意&题解&代码(C++)
- 笔试题:计算机网络 (1)
- Date Calender的问题
- FZU 1056扫雷游戏
- 逻辑地址、线性地址、物理地址和虚拟地址
- python的os模块fork、wait、system、exec、popen、exit函数讲解
- 【bzoj 2821】 作诗 题意&题解&代码(C++)
- hibernate查询方式
- IOS学习博客地址
- 227. Basic Calculator II LeetCode
- 安装APK运行Genymation时报错:Installation failed with message INSTALL_FAILED_CPU_ABI_INCOMPATIBLE.
- banner图片自适应
- MySQL数据库引擎介绍、区别、创建和性能测试的深入分析
- 冒泡排序C++
- String类型的 == 和 equals() 判断,及运算符优先级的问题