【NOI2017模拟6.23】回转寿司
来源:互联网 发布:linux 注销登录用户 编辑:程序博客网 时间:2024/04/29 13:46
题目大意
有n个人排成一个圆环,每个人初始有一个数字a[i],有m轮操作,每轮操作选择一段连续的人并给出一个数字x,按顺时针顺序比较x和a[i],如果x小于a[i],就那么交换a[i]和x
解法
考虑分块,那么对于一个块来说,如果当前某个数x进去了,那么出来的要不是x要不就是这个块的最大值,所以对每个块维护一个大根堆。
而对于块内的重构,由于本题有很好的性质:标记的处理和a[]的变化是具有对称性的,就是说重构时只要维护一个对于标记的小根堆,然后从左到右扫一遍。
Code
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>#include<set>#include<bitset>#include<map>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;typedef long long LL;typedef double db;int get(){ char ch; while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-'); if (ch=='-'){ int s=0; while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0'; return -s; } int s=ch-'0'; while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0'; return s;}const int N = 400010;const int Q = 25010;const int blk = 635;const int B = 640;int n,q;struct heap0{ int a[B]; int n; int& operator [](int x){return a[x];} int top(){return a[1];} void pop(){ int x=1; a[1]=a[n--]; while(x*2<=n){ int t=x*2; if (t<n&&a[t+1]>a[t])t++; if (a[t]<=a[x])break; swap(a[t],a[x]); x=t; } } void insert(int v){ a[++n]=v; int x=n; while(x>1&&a[x]>a[x>>1]){ swap(a[x],a[x>>1]); x>>=1; } }}a[B];struct heap1{ int a[Q]; int n; int& operator [](int x){return a[x];} int top(){return a[1];} void pop(){ int x=1; a[1]=a[n--]; while(x*2<=n){ int t=x*2; if (t<n&&a[t+1]<a[t])t++; if (a[t]>=a[x])break; swap(a[t],a[x]); x=t; } } void insert(int v){ a[++n]=v; int x=n; while(x>1&&a[x]<a[x>>1]){ swap(a[x],a[x>>1]); x>>=1; } }}t[B];int be[N],rig[N],lef[N];int val[N];void rebuild(int x){ a[x].n=0; if (!t[x].n)return; fo(i,lef[x],rig[x]){ int tp=t[x].top(); if (tp<val[i]){ t[x].pop(); t[x].insert(val[i]); val[i]=tp; } } t[x].n=0;}void putnew(int x){ a[x].n=0; fo(i,lef[x],rig[x])a[x][++a[x].n]=val[i]; sort(a[x].a+1,a[x].a+a[x].n+1); fo(i,1,a[x].n/2)swap(a[x][a[x].n-i+1],a[x][i]);}void solve(int l,int r,int &v){ if (be[l]==be[r]){ rebuild(be[l]); fo(i,l,r) if (v<val[i])swap(v,val[i]); putnew(be[l]); return; } int lt=be[l],rt=be[r]; if (l>lef[lt]){ rebuild(lt); for(int i=l;be[i]==lt;i++) if (v<val[i])swap(v,val[i]); putnew(lt); lt++; } if (r<rig[rt]){ fo(i,lt,rt-1){ int tp=a[i].top(); if (v<tp){ a[i].pop(); a[i].insert(v); t[i].insert(v); v=tp; } } rebuild(rt); fo(i,rig[rt-1]+1,r) if (v<val[i])swap(v,val[i]); putnew(rt); } else fo(i,lt,rt){ int tp=a[i].top(); if (v<tp){ a[i].pop(); a[i].insert(v); t[i].insert(v); v=tp; } }}int main(){ freopen("sushi.in","r",stdin); freopen("sushi.out","w",stdout); n=get();q=get(); fo(i,1,n)be[i]=i/blk+1; fo(i,1,n)rig[be[i]]=i; fd(i,n,1)lef[be[i]]=i; fo(i,1,n){ int x=get(); val[i]=x; a[be[i]].insert(x); } fo(cas,1,q){ int l=get(),r=get(),v=get(); if (l>r){ solve(l,n,v); solve(1,r,v); } else solve(l,r,v); printf("%d\n",v); } fclose(stdin); fclose(stdout); return 0;}
阅读全文
0 0
- 【NOI2017模拟6.23】回转寿司
- 回转寿司
- BZOJ4627 [BeiJing2016]回转寿司
- 4627: [BeiJing2016]回转寿司
- Bzoj4627: [BeiJing2016]回转寿司
- Bzoj4627:BeiJing2016-回转寿司
- 【BZOJ】4627 [BeiJing2016]回转寿司
- [BZOJ4627][BeiJing2016]回转寿司 cdq分治
- bzoj 4627: [BeiJing2016]回转寿司 线段树
- BZOJ 4627回转寿司(值域线段树)
- BZOJ4627 回转寿司(值域线段树)
- 【线段树】【CDQ分治】回转寿司
- BZOJ 4627: [BeiJing2016]回转寿司 cdq
- BZOJ 4627: [BeiJing2016]回转寿司【前缀和,值域线段树
- bzoj 4627 回转寿司(权值线段树)
- bzoj-4627 [BeiJing2016]回转寿司 hash+权值线段树
- [Noip模拟题]寿司
- NOI2017模拟3.1 总结
- HDU 2476 String painter
- POJ 1651 Multiplication Puzzle
- RSA加密算法 C++实现
- Java的Comparable接口&比较器原理
- BZOJ 2428: [HAOI2006]均分数据 模拟退火
- 【NOI2017模拟6.23】回转寿司
- Vim 使用
- 程序里面的异常
- 60. Permutation Sequence
- OpenCV自学笔记4:轮廓检测
- Oracle 数据库还原代码步骤
- Redis详解(原理,安装,配置,使用,命令)
- pycharm跳转到定义和声明,出现的问题:Cannot find declaration to go to
- Java中EventQueue.invokeLater干什么用的