【题目大意】

给一个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」回转寿司的更多相关文章

  1. 「6月雅礼集训 2017 Day7」电报

    [题目大意] 有n个岛屿,第i个岛屿有有向发射站到第$p_i$个岛屿,改变到任意其他岛屿需要花费$c_i$的代价,求使得所有岛屿直接或间接联通的最小代价. $1 \leq n \leq 10^5, 1 ...

  2. 「6月雅礼集训 2017 Day7」三明治

    [题目大意] $1 \leq n,m \leq 400$ N字形表示:上图第1行第1个那种:Z字形表示上图第1行第2个那种. [题解] 很容易得到结论: 考虑如果紫色比绿色先消去,那么黄色一定会比对应 ...

  3. 「6月雅礼集训 2017 Day10」quote

    [题目大意] 一个合法的引号序列是空串:如果引号序列合法,那么在两边加上同一个引号也合法:或是把两个合法的引号序列拼起来也是合法的. 求长度为$n$,字符集大小为$k$的合法引号序列的个数.多组数据. ...

  4. 「6月雅礼集训 2017 Day4」qyh(bzoj2687 交与并)

    原题传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2687 [题目大意] 给出若干区间,求一个区间的大于等于2的子集,使得 |区间并| 和 | ...

  5. 「6月雅礼集训 2017 Day11」delight

    [题目大意] 有$n$天,每天能吃饭.睡觉.什么事也不干 每天吃饭的愉悦值为$e_i$,睡觉的愉悦值为$s_i$,什么都不干愉悦值为0. 要求每连续$k$天都要有至少$E$天吃饭,$S$天睡觉. 求最 ...

  6. 「6月雅礼集训 2017 Day11」jump

    [题目大意] 有$n$个位置,每个位置有一个数$x_i$,代表从$i$经过1步可以到达的点在$[\max(1, i-x_i), \min(i+x_i, n)]$中. 定义$(i,j)$的距离表示从$i ...

  7. 「6月雅礼集训 2017 Day11」tree

    [题目大意] 给出一棵带权树,有两类点,一类黑点,一类白点. 求切断黑点和白点间路径的最小代价. $n \leq 10^5$ [题解] 直接最小割能过..但是树形dp明显更好写 设$f_{x,0/1/ ...

  8. 「6月雅礼集训 2017 Day10」perm(CodeForces 698F)

    [题目大意] 给出一个$n$个数的序列$\{a_n\}$,其中有些地方的数为0,要求你把这个序列填成一个1到$n$的排列,使得: $(a_i, a_j) = 1$,当且仅当$(i, j) = 1$.多 ...

  9. 「6月雅礼集训 2017 Day8」route

    [题目大意] 给出平面上$n$个点,求一条连接$n$个点的不相交的路径,使得转换的方向符合所给长度为$n-2$的字符串. $n \leq 5000$ [题解] 考虑取凸包上一点,然后如果下一个是‘R' ...

随机推荐

  1. NIO 服务端TCP连接管理的方案

    最近做的一个项目需要在服务端对连接端进行管理,故将方案记录于此. 方案实现的结果与背景 因为服务端与客户端实现的是长连接,所以需要对客户端的连接情况进行监控,防止无效连接占用资源. 完成类似于心跳的接 ...

  2. Android中的回调Callback

    回调就是外部设置一个方法给一个对象, 这个对象可以执行外部设置的方法, 通常这个方法是定义在接口中的抽象方法, 外部设置的时候直接设置这个接口对象即可. 例如给安卓添加按钮点击事件, 我们创建了OnC ...

  3. Android 开发错误集锦

    1. eclipse的Device中不显示手机 在eclipse中连接不上手机,出现adb server didn't ACK  fail to start daemon 错误. 出现这种原因是因为a ...

  4. 【IdentityServer4文档】- 支持和咨询选项

    支持和咨询选项 我们为 IdentityServer 提供多个免费和商业支持及咨询选项. 免费支持 免费支持是基于社区的,而且使用的是公共论坛 StackOverflow 有越来越多的使用 Ident ...

  5. parse_str — 将字符串解析成多个变量

    $arr2="first=value1&second=value2&third[]=value3&third[]=value4"; parse_str($a ...

  6. OSI参考模型和TCP/IP参考模型

  7. Java模块化开发

    包配置, 静态资源, 视图解析器, 数据库,

  8. VS2012完全卸载

    1.先交VS2012的ISO通过Ultraiso载入2.DOS命中输入 I:\vs_ultimate.exe /uninstall /force 或 I:vs_ultimate.exe /uninst ...

  9. 【bzoj4165】矩阵 堆+STL-map

    题目描述 定义和谐矩阵为长不小于 Mina 且宽不小于 Minb 的矩阵,矩阵的权值为整个矩阵内所有数的和.给定一个长为 N,宽为 M 的矩阵 A,求它的所有和谐子矩阵中权值第 K 小的矩阵,并输出它 ...

  10. 使用for循环遍历数组元素

    循环可以将代码块执行指定的次数.如果您希望一遍又一遍地运行相同的代码,并且每次的值都不同,那么使用循环是很方便的.迭代语句又叫循环语句. JavaScript 支持不同类型的循环: for - 循环代 ...