「6月雅礼集训 2017 Day7」回转寿司
【题目大意】
给一个n个数的序列,q次操作,每次选择区间$[l,r]$,给出数p,对于区间$[l,r]$的每个数$x$,做如下操作:
如果$x > p$,就交换$x$和$p$。求每次操作后$p$的值。
$1\leq n\leq 4\times 10^5, 1\leq q \leq 25000$
【题解】
这个q的范围就提示我们可以用根号算法了(逃)
由于有一个性质,p最后一定是变成[l,r]区间内最大的那个数,可是还要修改,所以我们需要分块。
我们对于区间分块,然后对于每个块维护一个堆存储元素,同时维护一个tag维护这个块被几个p给做过操作(由于做操作的时候,如果是一整块,那么我们知道这块做完后,答案一定是这块的最大值和p中取个最大的,所以我们不需要实际做操作,只要打个tag即可)
当访问到块内(头、尾),我们把块内的tag传到值上,我们一定是用tag这个堆里最小的跟区间的每个值依次比较,比较成功就交换,我们可以用堆。
还有一些优化就是我们用vector存tag,然后用强制类型转换来线性建堆(?)
我们修改直接应用在数组上,修改完,再把数组拿去线性建堆(?)
然后你96分了。。换一个读入优化板子就过了。
# include <queue>
# include <math.h>
# include <ctype.h>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull;
typedef long double ld; const int N = 4e5 + , M = 2e5 + , F = ; # define RG register
# define ST static int n, Q, BLOCK, B;
ST int a[N], bl[N];
ST int bg[F], ed[F]; #define BUFSIZE 300000
namespace fib {char b[BUFSIZE]={},*f=b;}
#define gc ((*fib::f)?(*(fib::f++)):(fgets(fib::b,sizeof(fib::b),stdin)?(fib::f=fib::b,*(fib::f++)):-1))
int g_i()
{
int tmp=; bool fu=; char s;
while(s=gc,s!='-'&&(s<''||s>'')) ;
if(s=='-') fu=; else tmp=s-'';
while(s=gc,s>=''&&s<='') tmp=tmp*+s-'';
if(fu) return -tmp; else return tmp;
}
#define gi g_i()
namespace fob {char b[BUFSIZE]={},*f=b,*g=b+BUFSIZE-;}
#define pob (fwrite(fob::b,sizeof(char),fob::f-fob::b,stdout),fob::f=fob::b,0)
#define pc(x) (*(fob::f++)=(x),(fob::f==fob::g)?pob:0)
struct foce {~foce() {pob; fflush(stdout);}} _foce;
namespace ib {char b[];}
inline void pint(int x)
{
if(x==) {pc(); return;}
if(x<) {pc('-'); x=-x;}
char *s=ib::b;
while(x) *(++s)=x%, x/=;
while(s!=ib::b) pc((*(s--))+);
} priority_queue<int> q[F];
vector<int> tag[F]; inline void rebuild(int id) {
RG int l = bg[id], r = ed[id];
q[id] = priority_queue<int> (a+l, a+r+);
} inline void tagdown(int id) {
if(!tag[id].size()) return ;
priority_queue < int, vector<int>, greater<int> > heap(tag[id].begin(), tag[id].end());
for (RG int i=bg[id], tp; i<=ed[id]; ++i) {
tp = heap.top();
if(a[i] > tp) {
heap.pop();
heap.push(a[i]);
a[i] = tp;
}
}
rebuild(id);
tag[id].clear();
} // tag down and force
inline int work(int id, int l, int r, int p) {
tagdown(id);
for (int i=l; i<=r; ++i) if(a[i] > p) swap(a[i], p);
rebuild(id);
return p;
} // cover whole
inline int work(int id, int p) {
RG int tp = q[id].top();
if(tp > p) {
tag[id].push_back(p);
q[id].pop();
q[id].push(p);
p = tp;
}
return p;
} inline int solve(int l, int r, int p) {
int BL = bl[l], BR = bl[r];
if(BL == BR) return work(BL, l, r, p);
else {
p = work(BL, l, ed[BL], p);
for (int i=BL+; i<BR; ++i) p = work(i, p);
return work(BR, bg[BR], r, p);
}
} int main() {
// freopen("sushi.in", "r", stdin);
// freopen("sushi.out", "w", stdout);
n = gi; Q = gi;
for (RG int i=; i<=n; ++i) a[i] = gi;
BLOCK = sqrt(n);
for (RG int i=; i<=n; ++i) bl[i] = (i-) / BLOCK + ;
B = bl[n];
for (RG int i=; i<=B; ++i) {
bg[i] = (i-) * BLOCK + ;
ed[i] = i * BLOCK;
if(i == B) ed[i] = n;
}
for (RG int i=; i<=n; ++i) q[bl[i]].push(a[i]);
RG int l, r, p;
while(Q --) {
l = gi, r = gi, p = gi;
if(l <= r) pint(solve(l, r, p)), pc();
else {
p = solve(l, n, p);
pint(solve(, r, p)), pc();
}
}
return ;
}
「6月雅礼集训 2017 Day7」回转寿司的更多相关文章
- 「6月雅礼集训 2017 Day7」电报
[题目大意] 有n个岛屿,第i个岛屿有有向发射站到第$p_i$个岛屿,改变到任意其他岛屿需要花费$c_i$的代价,求使得所有岛屿直接或间接联通的最小代价. $1 \leq n \leq 10^5, 1 ...
- 「6月雅礼集训 2017 Day7」三明治
[题目大意] $1 \leq n,m \leq 400$ N字形表示:上图第1行第1个那种:Z字形表示上图第1行第2个那种. [题解] 很容易得到结论: 考虑如果紫色比绿色先消去,那么黄色一定会比对应 ...
- 「6月雅礼集训 2017 Day10」quote
[题目大意] 一个合法的引号序列是空串:如果引号序列合法,那么在两边加上同一个引号也合法:或是把两个合法的引号序列拼起来也是合法的. 求长度为$n$,字符集大小为$k$的合法引号序列的个数.多组数据. ...
- 「6月雅礼集训 2017 Day4」qyh(bzoj2687 交与并)
原题传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2687 [题目大意] 给出若干区间,求一个区间的大于等于2的子集,使得 |区间并| 和 | ...
- 「6月雅礼集训 2017 Day11」delight
[题目大意] 有$n$天,每天能吃饭.睡觉.什么事也不干 每天吃饭的愉悦值为$e_i$,睡觉的愉悦值为$s_i$,什么都不干愉悦值为0. 要求每连续$k$天都要有至少$E$天吃饭,$S$天睡觉. 求最 ...
- 「6月雅礼集训 2017 Day11」jump
[题目大意] 有$n$个位置,每个位置有一个数$x_i$,代表从$i$经过1步可以到达的点在$[\max(1, i-x_i), \min(i+x_i, n)]$中. 定义$(i,j)$的距离表示从$i ...
- 「6月雅礼集训 2017 Day11」tree
[题目大意] 给出一棵带权树,有两类点,一类黑点,一类白点. 求切断黑点和白点间路径的最小代价. $n \leq 10^5$ [题解] 直接最小割能过..但是树形dp明显更好写 设$f_{x,0/1/ ...
- 「6月雅礼集训 2017 Day10」perm(CodeForces 698F)
[题目大意] 给出一个$n$个数的序列$\{a_n\}$,其中有些地方的数为0,要求你把这个序列填成一个1到$n$的排列,使得: $(a_i, a_j) = 1$,当且仅当$(i, j) = 1$.多 ...
- 「6月雅礼集训 2017 Day8」route
[题目大意] 给出平面上$n$个点,求一条连接$n$个点的不相交的路径,使得转换的方向符合所给长度为$n-2$的字符串. $n \leq 5000$ [题解] 考虑取凸包上一点,然后如果下一个是‘R' ...
随机推荐
- FZU.Software Engineering1816 · First Homework -Preparation
Introduction 041602204 : 我是喜欢狗狗(particularly Corgi & Shiba Inu.)的丁水源 : 我的爱好是音乐.电影.英语(100%!!!!).吉 ...
- java---迭代器(Iterator)
迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭代器通常被称为“轻量级”对象,因为创建它的代价小. Java中的Iterator功能比较简单, ...
- TCP系列13—重传—3、协议中RTO计算和RTO定时器维护
从上一篇示例中我们可以看到在TCP中有一个重要的过程就是决定何时进行超时重传,也就是RTO的计算更新.由于网络状况可能会受到路由变化.网络负载等因素的影响,因此RTO也必须跟随网络状况动态更新.如果T ...
- 3ds max启动慢怎么办?
有时候启动3ds max的时候一直卡在启动界面进不去怎么办? 在百度上搜到了下面这个解决方案,试了下还真有用: 具体就是进到这个文件夹,然后分别进入第一个和第三个文件夹删掉autodesk ...
- 关于c中的一些新函数
localtime 和 localtime_s: localtime:localtime(const time_t * _Time) time_t t;struct tm *local;time(&a ...
- 发送tcp的时候,数据包是如何拷贝的
发送数据包的时候,用户态的数据包是如何拷贝到内核的kiovec msghd 结构体 icmp是走sock吗? 每一个skb_buffer的大小都是固定的吗?所以有skb_available这样的函数 ...
- jQuery返回顶部代码
页面较长时,使用返回顶部按钮比较方便,在电商中必备操作.下面自己制作一个js文件,totop.js,把它直接引用到需要的网页中即可. $(function () { $("body" ...
- 2011 Multi-University Training Contest 4 - Host by SDU
A.Color the Simple Cycle(polya计数+字符串匹配) 此题的难点在于确定置换的个数,由a[i+k]=a[i], e[i+k]=e[i]联想到KMP. 于是把原串和原串扩大两倍 ...
- 项目管理---git----快速使用git笔记(二)------git的本地安装
下载安装包 在使用Git前我们需要先安装 Git.Git 目前支持 Linux/Unix.Solaris.Mac和 Windows 平台上运行. Git 各平台安装包下载地址为:http://git- ...
- Linux系统通过AWS命令行上传文件至S3
打开你的AWS控制台: 在IAM中创建一个新用户(比如test),创建时它会自动创建一个用户安全凭证,是由“访问密钥ID”和“私有访问密钥”组成的,请记住它并下载该凭证,后面会用到它: 选择你刚创建的 ...