P4855 MloVtry的idea
$ \color{#0066ff}{ 题目描述 }$
MloVtry是一个脑洞很大的人,它总会想出一些奇奇怪怪的idea。
可问题是,MloVtry作为一个蒟蒻,很多时候都没办法解决自己提出的问题,所以MloVtry想出一套题的梦想一直被搁置。
不过好在MloVtry有一些神犇朋友,他们强的没边,所以MloVtry一有机会就会向这些dalao们请教。
现在MloVtry有n个idea,这n个idea在MloVtry二维的大脑里排成一列,每一个idea都有一个难度值,用a[i]表示,当然难度值越大越困难。
MloVtry准备与q个神犇进行交♂易,但是MloVtry不想问一些过于简单的idea来降自己的B格,又不好意思用太难的、无法解决的idea来伤害自己与神犇之间的感情,所以它每次都会挑idea序列中的第k简单的idea来向神犇询问(也就是难度值第k小的那个idea)。
MloVtry的脑子有坑,但是没关系,这个坑会反而会帮助MloVtry思考,不过这样数列的a[i]就会更新,具体的,设坑在第j个idea上,那么a[i]=a[i]-zz(i<=j);a[i]=i+a[i]-j(i>j)。
如果仅仅如此MloVtry也不会感到迷茫,但关键的是这个坑还会不定时的跳跃,这就让MloVtry手足无措了---它不知道这个时候要问哪个问题了。
现在MloVtry会给出你---它最好的朋友一些询问---一些二元组(at,k),表示脑洞位于at,且它想询问第k简单的idea,请你告诉MloVtry这个idea难度是多少。
\(\color{#0066ff}{输入格式}\)
第一行三个整数n,q,zz,含义见题面
第二行n个整数a[1],a[2].....a[n]
随后q行,每行两个整数表示at与k
特别的,MloVtry是一个三维生物,所以它无法想象有人可以在时间轴上翻滚,所以at与k与上一个询问的答案的绝对值的异或值并对n取膜后再+1的值为本次的at和k。
(也就是设lastans为上次询问答案,每一次at=(atabs(lastans))%n+1,k=(kabs(lastans))%n+1,并将lastans更新,初始lastans=0)
\(\color{#0066ff}{输出格式}\)
q行q个整数,表示对每个询问的回答
\(\color{#0066ff}{输入样例}\)
13 12 56
10100 12208 11766 11872 11336 10815 10710 11872 11536 11988 10100 10908 10815
11 13
1 3
3 10
1 7
8 4
7 11
11 4
5 2
13 11
13 6
3 11
11 10
\(\color{#0066ff}{输出样例}\)
10044
11932
10918
11280
10044
10759
10827
11874
12152
10759
10044
10713
\(\color{#0066ff}{数据范围与提示}\)
各个值保证在int范围内。
对于100%的数据,n,q<=6w。
对于40%的数据,n,q<=1000。
PS.可能有重复,例如
1 1 1 1 1 0
此时第1大、第2大....第5大的值都是1,第6大的值是0
\(\color{#0066ff}{题解}\)
对序列\(a[i]-zz和a[i]+i\)分别开一个主席树
然后对于每次询问, 二分答案,分别在两个主席树上找\(\le mid和\le mid+at\)的数的个数,从而缩小范围
总复杂度\(O(nlog^2n)\)
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int inf = 0x7fffffff;
const int maxn = 1e5 + 10;
struct Tree {
protected:
struct node {
node *ch[2];
int num;
node(int num = 0): num(num) { ch[0] = ch[1] = NULL; }
}*root[maxn];
int L, R;
void add(node *&o, node *lst, int l, int r, int pos) {
o = new node();
*o = *lst;
o->num++;
if(l == r) return;
LL mid = ((LL)(l + r)) >> 1;
if(pos <= mid) add(o->ch[0], lst->ch[0], l, mid, pos);
else add(o->ch[1], lst->ch[1], mid + 1, r, pos);
}
int query(node *x, node *y, int ql, int qr, int l, int r) {
if(ql <= l && r <= qr) return y->num - x->num;
if(x->num == y->num) return 0;
LL mid = ((LL)(l + r)) >> 1, ans = 0;
if(ql <= mid) ans += query(x->ch[0], y->ch[0], ql, qr, l, mid);
if(qr > mid) ans += query(x->ch[1], y->ch[1], ql, qr, mid + 1, r);
return ans;
}
public:
Tree() {
root[0] = new node();
root[0]->ch[0] = root[0]->ch[1] = root[0];
}
void resize(int l, int r) { L = l, R = r; }
void init(int n, int *a) { for(int i = 1; i <= n; i++) add(root[i], root[i - 1], L, R, a[i]); }
int query(int l, int r, int val) { return query(root[l - 1], root[r], L, val, L, R); }
}f, g;
int a[maxn], b[maxn];
int abs(int x) { return x > 0? x : -x; }
int main() {
int n = in(), q = in(), zz = in();
int max = -inf, min = inf;
for(int i = 1; i <= n; i++) {
a[i] = in();
b[i] = a[i] + i;
a[i] = a[i] - zz;
max = std::max(max, std::max(a[i], b[i]));
min = std::min(min, std::min(a[i], b[i]));
}
f.resize(min, max), g.resize(min, max);
f.init(n, a), g.init(n, b);
int at, k, ans = 0;
while(q --> 0) {
at = (in() ^ abs(ans)) % n + 1;
k = (in() ^ abs(ans)) % n + 1;
LL l = min, r = max;
while(l <= r) {
LL mid = (l + r) >> 1;
if(k <= f.query(1, at, mid) + g.query(at + 1, n, mid + at)) r = mid - 1, ans = mid;
else l = mid + 1;
}
printf("%d\n", ans);
}
return 0;
}
P4855 MloVtry的idea的更多相关文章
- P4854 MloVtry的咸鱼树 状压+最短路
$ \color{#0066ff}{ 题目描述 }$ 俗话说种瓜得瓜,种豆得豆,MloVtry把自己砍掉一半埋进了土里,于是它得到了一颗n个点的咸鱼树. 但是问题是由于MloVtry只舍得埋下一半的自 ...
- RedMine项目管理系统安装问题(Windows版一键安装包)
安装准备: 操作环境:VMware10 下安装的windows10 系统 使用软件:<bitnami-redmine---windows-installer.exe> 问题描述: 安装过程 ...
- ghj1222被坑记录[不持续更新]
考试注意事项:link1 link2 (密码:wangle) 调不出来bug,可以先透彻一会儿或者是上个厕所或者坐一会别的题(间隔至少20min),然后通读代码 -1. 考试先读题,读题之后搞出一个做 ...
随机推荐
- export LD_LIBRARY_PATH 的使用
对linux不是很熟,之前只是听说过可以设置程序共享库位置也就是 使用 “export LD_LIBRARY_PATH” 今天用了用,感觉还挺不错,也很常用. 比如你编译了一个so 而这个so 同时又 ...
- DataSet、DataTable转换List(泛型集合与DataSet互相转换 )
using System.Data; using System.Reflection; using System.Collections; using System.Collections.Gener ...
- libevent源码深度剖析十一
libevent源码深度剖析十一 ——时间管理 张亮 为了支持定时器,Libevent必须和系统时间打交道,这一部分的内容也比较简单,主要涉及到时间的加减辅助函数.时间缓存.时间校正和定时器堆的时间值 ...
- 嵌入式Qt开发环境的搭建详解
一.嵌入式Qt开发环境的搭建前奏 1.下载arm-linux-gcc-4.4.3-20100728.tar.gz 2.下载qt-everywhere-opensource-src-4.8.5.tar. ...
- Linux扩展根目录
一.简介 使用linux系统的过程中,有时发现系统根目录(/)的空间不足,导致系统运行很慢,针对该现象,本文详细介绍根目录(/)的空间扩展方法. 二.操作步骤 1)查看根目录大小 df 2)查找系 ...
- 9.hive聚合函数,高级聚合,采样数据
本文主要使用实例对Hive内建的一些聚合函数.分析函数以及采样函数进行比较详细的讲解. 一.基本聚合函数 数据聚合是按照特定条件将数据整合并表达出来,以总结出更多的组信息.Hive包含内建的一些基本聚 ...
- 彻底清除Window7下的360注册表
当流氓360遇到强迫症,将注定有一场厮杀... 今天装了个虚拟机,其中win7系统是在网上随便下载了一个,是非纯净版的,自带了360在内的好多软件,其他软件都轻松删掉,但查看注册表时发现竟然有360残 ...
- su 和sudo su 的区别
su "user" 执行该命令,需要输入password,它是"user"中定义的用户的password,即,要变换成的用户的password.(如果已经用ro ...
- Install zlib/libpng/jpeg/freetype/libgd/GD on Mavericks即mac10.9(转)
转自:http://wangqinhu.com/install-gd-on-mavericks/ Various applications depend on library GD, however, ...
- Vim编码知识,乱码问题
原文:http://demi-panda.com/2012/12/26/vim-encoding/ 在vim的初始学习阶段,乱码经常是困扰新手的一个比较烦躁的问题,本文试图阐述Vim的编码知识,及设置 ...