JZOJ 5431. 【NOIP2017提高A组集训10.28】序列操作
来源:互联网 发布:星际战甲腐蚀投射数据 编辑:程序博客网 时间:2024/06/07 01:41
Description
一开始有n个非负整数hi,接下来会进行m次操作,第i次操作给出一个数c[i],要求你选出c[i]个大于零的数并将它们减去1。
问最多可以进行多少轮操作后无法操作(即没有c[i]个大于零的数)
Input
第一行两个数表示n和m
第二行n个数描述h[i]
第三行m个数描述c[i]
Output
一行表示答案,即最多可以进行多少轮操作后无法操作
Sample Input
输入1:
3 5
1 2 5
1 2 3 2 1
输入2:
5 5
1 3 3 4 5
1 2 4 4 4
Sample Output
输出1:
3
输出2:
5
Data Constraint
对于10%的数据满足,1<=n,m<=5
对于另外20%的数据满足,1<=n<=8,1<=h[i]<=7
对于50%的数据满足,1<=n,m<=1000
对于80%的数据满足,1<=n,m<=100000
对于100%的数据满足,1<=n,m<=1000000
Solution
虽然数据有点大,还是决定线段树……
显然,选择的
c 个数一定选最大的那c 个。为了方便处理,先把数组排序,中途维护时也保证单调。
区间减,如果第
n−c+1 个数属于一段相同的数,就把相同的那段移到前面减(保证单调)。时间复杂度
O(N log N) 。
Code
#include<cstdio>#include<algorithm>using namespace std;const int N=1e6+2;struct data{ int mx,c;}f[N<<2];int ans;int a[N];inline int read(){ int X=0,w=1; char ch=0; while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();} while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar(); return X*w;}inline int max(int x,int y){ return x>y?x:y;}inline void modify(int v){ if(f[v].c) { int ls=v<<1,rs=ls|1; f[ls].c+=f[v].c; f[rs].c+=f[v].c; f[ls].mx-=f[v].c; f[rs].mx-=f[v].c; f[v].c=0; }}inline void make(int v,int l,int r){ if(l==r) { f[v].mx=a[l]; return; } int mid=(l+r)>>1; make(v<<1,l,mid); make(v<<1|1,mid+1,r); f[v].mx=max(f[v<<1].mx,f[v<<1|1].mx);}inline void change(int v,int l,int r,int x,int y){ if(l==x && r==y) { f[v].c++; f[v].mx--; return; } modify(v); int mid=(l+r)>>1; if(y<=mid) change(v<<1,l,mid,x,y); else if(x>mid) change(v<<1|1,mid+1,r,x,y); else { change(v<<1,l,mid,x,mid); change(v<<1|1,mid+1,r,mid+1,y); } f[v].mx=max(f[v<<1].mx,f[v<<1|1].mx);}inline int findnum(int v,int l,int r,int x){ modify(v); if(l==r) return f[v].mx; int mid=(l+r)>>1; int t=x<=mid?findnum(v<<1,l,mid,x):findnum(v<<1|1,mid+1,r,x); f[v].mx=max(f[v<<1].mx,f[v<<1|1].mx); return t;}inline int findpos(int v,int l,int r,int x){ modify(v); if(l==r) return l; int mid=(l+r)>>1; int t=f[v<<1].mx>=x?findpos(v<<1,l,mid,x):findpos(v<<1|1,mid+1,r,x); f[v].mx=max(f[v<<1].mx,f[v<<1|1].mx); return t;}int main(){ int n=read(),m=read(); for(int i=1;i<=n;i++) a[i]=read(); sort(a+1,a+1+n); make(1,1,n); for(ans=0;ans<m;ans++) { int x=read(),t=findnum(1,1,n,n-x+1); if(t<=0) break; int pos2=findpos(1,1,n,t); if(pos2<n-x+1) { int pos1=findpos(1,1,n,t+1); if(pos1<=n && findnum(1,1,n,pos1)<=t) pos1++; if(pos1<=n) change(1,1,n,pos1,n); if(pos2+pos1-(n-x+1)-1<=n && pos2+pos1-(n-x+1)-1>=pos2) change(1,1,n,pos2,pos2+pos1-(n-x+1)-1); }else change(1,1,n,n-x+1,n); } printf("%d",ans); return 0;}
阅读全文
1 0
- JZOJ 5431. 【NOIP2017提高A组集训10.28】序列操作
- 【JZOJ 5431】【NOIP2017提高A组集训10.28】序列操作
- 【JZOJ5431】【NOIP2017提高A组集训10.28】序列操作
- JZOJ5431. 【NOIP2017提高A组集训10.28】序列操作
- 【NOIP2017提高A组集训10.28】序列操作
- 【NOIP2017提高A组集训10.28】序列操作
- JZOJ 5432. 【NOIP2017提高A组集训10.28】三元组
- 【JZOJ 5432】【NOIP2017提高A组集训10.28】三元组
- 【JZOJ 5433】【NOIP2017提高A组集训10.28】图
- jzoj【NOIP2017提高A组集训10.28】图
- JZOJ 5407. 【NOIP2017提高A组集训10.21】Deep
- JZOJ 5408. 【NOIP2017提高A组集训10.21】Dark
- 【JZOJ 5409】【NOIP2017提高A组集训10.21】Fantasy
- JZOJ 5410. 【NOIP2017提高A组集训10.22】小型耀斑
- 【JZOJ 5410】【NOIP2017提高A组集训10.22】小型耀斑
- 【JZOJ 5411】【NOIP2017提高A组集训10.22】友谊
- JZOJ 5414. 【NOIP2017提高A组集训10.22】幸运值
- JZOJ 5407. 【NOIP2017提高A组集训10.21】Deep
- 用python实现PAT1057数零壹
- jQuery之位置操作
- 洛谷P1190 接水问题(接个水事情都这么多qwq)
- MSCOMM32串口编程循环读取数据
- vim的使用大全
- JZOJ 5431. 【NOIP2017提高A组集训10.28】序列操作
- Python Imaging Library:ImageDraw Module(图像绘制模块)
- SDNU OJ 1060.找第K大数
- 成为一名高级java工程师需要读那些书
- 【考研】第九周总结
- JS BOM
- Linux学习总结
- bzoj1226 [SDOI2009]学校食堂Dining 状压DP
- kafka Consumer详解