BZOJ 2427 & 分块裸题
题意:
求区间内的众数,强制在线.
SOL:
推荐一个大神犇的blog,讲的还是很好的(主要我喜欢他的代码风格(逃:http://www.cnblogs.com/JoeFan/p/4248767.html
太裸没什么意思...虽然好些但码码也挺长的...
还是贴那个大神的代码天天看着代码打的会不会好看点>_<
- #include <iostream>
- #include <cstdlib>
- #include <cstdio>
- #include <algorithm>
- #include <cstring>
- #include <cmath>
- using namespace std;
- inline void Read(int &Num) {
- char c; c = getchar();
- while (c < '0' || c > '9') c = getchar();
- Num = c - '0'; c = getchar();
- while (c >= '0' && c <= '9') {
- Num = Num * 10 + c - '0';
- c = getchar();
- }
- }
- const int MaxN = 40000 + 5, MaxBlk = 200 + 5;
- int n, m, BlkSize, TotBlk;
- int A[MaxN], TL[MaxN], T[MaxN], Cnt[MaxN], L[MaxBlk], R[MaxBlk], First[MaxN], Last[MaxN];
- int f[MaxBlk][MaxBlk], g[MaxBlk][MaxBlk];
- struct ES
- {
- int Pos, Num, v;
- } E[MaxN];
- inline bool Cmp_Num(ES e1, ES e2) {
- if (e1.Num == e2.Num) return e1.Pos < e2.Pos;
- return e1.Num < e2.Num;
- }
- inline bool Cmp_Pos(ES e1, ES e2) {return e1.Pos < e2.Pos;}
- int GetNum(int Num, int x, int y) {
- if (x > y || x > E[Last[Num]].Pos || y < E[First[Num]].Pos) return 0;
- int l, r, mid, p1, p2;
- l = First[Num]; r = Last[Num];
- while (l <= r) {
- mid = (l + r) >> 1;
- if (E[mid].Pos >= x) {
- p1 = mid;
- r = mid - 1;
- }
- else l = mid + 1;
- }
- l = First[Num]; r = Last[Num];
- while (l <= r) {
- mid = (l + r) >> 1;
- if (E[mid].Pos <= y) {
- p2 = mid;
- l = mid + 1;
- }
- else r = mid - 1;
- }
- return p2 - p1 + 1;
- }
- int main()
- {
- Read(n); Read(m);
- for (int i = 1; i <= n; ++i) {
- Read(E[i].Num);
- E[i].Pos = i;
- }
- sort(E + 1, E + n + 1, Cmp_Num);
- int v_Index = 0;
- for (int i = 1; i <= n; ++i) {//离散化
- if (i == 1 || E[i].Num > E[i - 1].Num) ++v_Index;
- E[i].v = v_Index;
- TL[v_Index] = E[i].Num;//再映射回来
- }
- sort(E + 1, E + n + 1, Cmp_Pos);
- for (int i = 1; i <= n; ++i) A[i] = E[i].v;
- sort(E + 1, E + n + 1, Cmp_Num);
- //三次排序感觉真是浪费啊...
- for (int i = 1; i <= n; ++i) {
- if (First[E[i].v] == 0) First[E[i].v] = i;
- Last[E[i].v] = i;
- }//数字段的头尾
- BlkSize = (int)sqrt((double)n);
- TotBlk = (n - 1) / BlkSize + 1;//很不错的技巧啊
- for (int i = 1; i <= TotBlk; ++i) {//块两头
- L[i] = (i - 1) * BlkSize + 1;
- R[i] = i * BlkSize;
- }
- R[TotBlk] = n;
- for (int i = 1; i <= TotBlk; ++i) {
- for (int j = 1; j <= n; ++j) Cnt[j] = 0;
- f[i][i - 1] = 0; g[i][i - 1] = 0;
- for (int j = i; j <= TotBlk; ++j) {
- f[i][j] = f[i][j - 1];
- g[i][j] = g[i][j - 1];
- for (int k = L[j]; k <= R[j]; ++k) {
- ++Cnt[A[k]];
- if (Cnt[A[k]] > f[i][j] || (Cnt[A[k]] == f[i][j] && A[k] < g[i][j])) {
- f[i][j] = Cnt[A[k]]; g[i][j] = A[k];//次数和数
- }
- }
- }
- }
- memset(Cnt, 0, sizeof(Cnt));
- for (int i = 1; i <= n; ++i) T[i] = -1;
- int l, r, x, y, Ct, Ans, Cu;
- Ans = 0;
- for (int i = 1; i <= m; ++i) {
- Read(l); Read(r);
- l = (l + Ans - 1) % n + 1; r = (r + Ans - 1) % n + 1;//强制在线
- if (l > r) swap(l, r);
- x = (l - 1) / BlkSize + 1; if (l != L[x]) ++x;
- y = (r - 1) / BlkSize + 1; if (r != R[y]) --y;
- if (x > y) {
- Ct = 0; Ans = 0;
- for (int j = l; j <= r; ++j) {
- ++Cnt[A[j]];
- if (Cnt[A[j]] > Ct || (Cnt[A[j]] == Ct && A[j] < Ans)) {
- Ct = Cnt[A[j]]; Ans = A[j];
- }
- }
- for (int j = l; j <= r; ++j) --Cnt[A[j]];
- }
- else {
- Ct = f[x][y]; Ans = g[x][y];
- for (int j = l; j < L[x]; ++j) {
- ++Cnt[A[j]];
- if (T[A[j]] == -1) T[A[j]] = GetNum(A[j], L[x], R[y]);
- Cu = Cnt[A[j]] + T[A[j]];
- if (Cu > Ct || (Cu == Ct && A[j] < Ans)) {
- Ct = Cu; Ans = A[j];
- }
- }
- for (int j = r; j > R[y]; --j) {
- ++Cnt[A[j]];
- if (T[A[j]] == -1) T[A[j]] = GetNum(A[j], L[x], R[y]);
- Cu = Cnt[A[j]] + T[A[j]];
- if (Cu > Ct || (Cu == Ct && A[j] < Ans)) {
- Ct = Cu; Ans = A[j];
- }
- }
- for (int j = l; j < L[x]; ++j) {--Cnt[A[j]]; T[A[j]] = -1;}
- for (int j = r; j > R[y]; --j) {--Cnt[A[j]]; T[A[j]] = -1;}
- }
- Ans = TL[Ans];
- printf("%d\n", Ans);
- }
- return 0;
- }
BZOJ 2427 & 分块裸题的更多相关文章
- BZOJ 3771 母函数裸题
题目描述 我们讲一个悲伤的故事. 从前有一个贫穷的樵夫在河边砍柴. 这时候河里出现了一个水神,夺过了他的斧头,说: “这把斧头,是不是你的?” 樵夫一看:“是啊是啊!” 水神把斧头扔在一边,又拿起一个 ...
- BZOJ 2427 [HAOI2010]软件安装 | 这道树形背包裸题严谨地证明了我的菜
传送门 BZOJ 2427 题解 Tarjan把环缩成点,然后跑树形背包即可. 我用的树形背包是DFS序上搞的那种. 要注意dp数组初始化成-INF! 要注意dp顺推的时候也不要忘记看数组是否越界! ...
- BZOJ 3680: 吊打XXX【模拟退火算法裸题学习,爬山算法学习】
3680: 吊打XXX Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 3192 Solved: 1198[Sub ...
- BZOJ 1061: [Noi2008]志愿者招募【单纯形裸题】
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 4813 Solved: 2877[Submit][Stat ...
- BZOJ 2724 蒲公英 | 分块模板题
题意 给出一个序列,在线询问区间众数.如果众数有多个,输出最小的那个. 题解 这是一道分块模板题. 一个询问的区间的众数,可能是中间"整块"区间的众数,也可能是左右两侧零散的数中的 ...
- BZOJ第一页刷题计划
BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...
- [BZOJ 2427] 软件安装
Link: BZOJ 2427 传送门 Solution: 只看样例的话会以为是裸的树形$dp$…… 但实际上题目并没有说明恰好仅有一个物品没有依赖项 因此原图可能由是由多棵树与多个图组成的 先跑一遍 ...
- 刷题向》POJ2823 单调队列裸题(<不会做,请自裁>系列)
最近BZOJ炸了,而我的博客上又更新了一些基本知识,所以这里刷一些裸题,用以丰富知识性博客 POJ2823 滑动的窗口 这是一道经典的单调队题,我记得我刚学的时候就是用这道题作为单调队列的例题,算 ...
- loj6277 数列分块入门题1
裸题分块. #include <bits/stdc++.h> using namespace std; ],b[],n,m,t1,t2,t3,t4,sq; int main(){ ios: ...
随机推荐
- struts2中一些常用的写法 记录
1.对日期进行处理 Date current = new Date(); java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat ...
- cache buffers
buffers缓冲,可以型象的理解为漏斗.如果有大量的数据要写入磁盘,由于数据量很大,磁盘不能一下子接收,所以这个时候,就有了buffer这个漏斗,先把数据放入这个漏斗里面,然后让它慢慢的注入磁盘,这 ...
- Clr Via C#读书笔记---程序集的加载和反射
#1 加载程序集 Assembly.Load: public class Assembly { public static Assembly Load(AssemblyName assemblyRef ...
- djcelery的细节篇
http://blog.csdn.net/samed/article/details/50598371 随时撸一撸,要点记心间.. 1. 下面讲解一下celery.py文件的配置内容,为何要这么配置. ...
- Oracle的thin驱动和oci驱动有什么不同?哪个性能好些?
OCI:要安装ORACLE客户端,移植性略差,理论上性能好些 THIN:属于TYPE4,纯JAVA实现,移植性好,理论上性能略差些 推荐:最好还是使用THIN DRIVER吧,移植性好些,使用起来 ...
- 自制工具:迅速打开一个Node 环境的Playground
需求 经常有这种情况,写代码的时候需要实验种想法,亟需一种playground 环境来玩耍.如果是前端的话可以打开chrome 的控制台,但是如果是Node 的话就比较麻烦了.我要打开我的存放试验代码 ...
- [LeetCode] Remove Duplicates from Sorted Array
Given a sorted array, remove the duplicates in place such that each element appear only once and ret ...
- Spring XML配置文件示例(一)——<Servlet name>-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- Oracle 【IT实验室】数据库备份与恢复之一:exp/imp(导出与导入&装库与卸库)
1.1 基本命令 1. 获取帮助 $ exp help=y $ imp help=y 2. 三种工作方式 (1)交互式方式 $ exp // 然后按提示输入所需要的参数 ...
- 7-13IN和NOT IN 子查询
IN后面的子查询可以返回多条记录. SELECT ...FROM WHERE 查询表达式 IN(子查询) 常用IN替换等于(=)的比较子查询. 用法: (1)使用 :IN关键字可以使父查询匹配子查询 ...