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

  • 虽然数据有点大,还是决定线段树……

  • 显然,选择的 cc 个数一定选最大的那 cc 个。

  • 为了方便处理,先把数组排序,中途维护时也保证单调。

  • 区间减,如果第 n−c+1n-c+1 个数属于一段相同的数,就把相同的那段移到前面减(保证单调)。

  • 时间复杂度 O(N log N)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); elseif(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;
}

JZOJ 5431. 【NOIP2017提高A组集训10.28】序列操作相关推荐

  1. JZOJ 5417. 【NOIP2017提高A组集训10.24】方阵

    Description 题目背景 热烈庆祝北京师范大学附属实验中学成立100周年! 问题描述 为了准备校庆庆典,学校招募了一些学生组成了一个方阵,准备在庆典上演出. 这个方阵是一个n*m的矩形,第i行 ...

  2. JZOJ 5438. 【NOIP2017提高A组集训10.31】Tree

    Description Input Output Sample Input 10 1 1 0 0 1 0 0 0 0 0 1 2 2 3 2 4 4 5 2 6 6 7 7 8 7 9 4 10 Sa ...

  3. JZOJ 5439. 【NOIP2017提高A组集训10.31】Calculate

    Description Input Output Data Constraint Solution 设前缀和 g[i][j]g[i][j] 表示 AA 为 ii .BB%A 为 jj 的数量. 这样就 ...

  4. JZOJ 5436. 【NOIP2017提高A组集训10.30】Group

    Description Input Output Sample Input 10 113 28 3 39 90 46 14 55 35 48 47 Sample Output 62453 Data C ...

  5. JZOJ 5426. 【NOIP2017提高A组集训10.25】摘Galo

    Description 0v0在野外看到了一棵Galo树,看到食物的0v0瞪大了眼睛,变成了OvO. 这棵Galo树可以看做是一棵以1号点为根的n个点的有根数,除了根节点以外,每个节点i都有一个Gal ...

  6. JZOJ 5419. 【NOIP2017提高A组集训10.24】筹备计划

    Description 题目背景 热烈庆祝北京师范大学附属实验中学成立100周年! 问题描述 校庆筹备组的老师们正在寻找合适的地方来举办校庆庆典.学生们的位置和可以举办庆典的位置在x轴的正半轴取值在[ ...

  7. JZOJ 5421. 【NOIP2017提高A组集训10.25】嘟嘟噜

    Description 由于众所周知的原因, 冈部一直欠真由理一串香蕉. 为了封上真由理的嘴, 冈部承诺只要真由理回答出这个问题, 就给她买一车的香蕉: 一开始有n 个人围成一个圈, 从1 开始顺时针 ...

  8. JZOJ 5425. 【NOIP2017提高A组集训10.25】数论

    Description 聪明的0v0正在学习莫比乌斯反演. 她看到了这样的一道题:有n*m个人站成了一个n*m的方阵-- 剩下的题面,聪明的0v0不记得了.但是,她通过自己高超的数论技巧,给出了一个转 ...

  9. JZOJ 5422. 【NOIP2017提高A组集训10.25】天才绅士少女助手克里斯蒂娜

    Description Input 第一行两个整数n;m 表示电子个数和询问个数. 接下来n 行, 每行两个整数x; y 表示vi. 接下来m 行, 每行形如1 p x y 或2 l r, 分别表示两 ...

最新文章

  1. java基础之继承补充和抽象类
  2. mysql数据库---授权语句以及备份
  3. 更优雅地判断iOS设备类型
  4. 【哲学】《哲学的故事》笔记
  5. 局域网win7计算机如何互访,局域网win7电脑的互访步骤
  6. Jquery easy ui datagrid動態加載列問題
  7. java正则匹配性能,Java正则表达式的性能问题
  8. 计算机专业复试有英语口语吗,计算机考研复试英语口语技巧
  9. 怎么批量在文件名前面加上数字序号,对文件进行编号排序?
  10. java随笔 2008年
  11. 第七篇 indicators(4)自建指标
  12. 软件工程——结构化分析方法
  13. wpf打开默认浏览器网址
  14. Win7, VS2019下, pywin32安装
  15. 低延时应用 服务器TurboBoost不可得兼?
  16. 杰理芯片移植涂鸦OTA步骤
  17. 争夺切客【南方周末】
  18. linux如何安装vi命令,Ubuntu 16.04 下 Vim安装及配置
  19. 【web渗透】CSRF漏洞详细讲解
  20. 基于Anaconda 搭建 OpenCV for Python 环境(全平台通用)

热门文章

  1. 找出指定范围的回文数C++代码实现
  2. 《TCP/IP Socket in C》阅读笔记
  3. Linux内核源代码获取方法
  4. 软件包管理 rpm yum apt-get dpkg
  5. Qt中Ui名字空间以及setupUi函数的原理和实现
  6. [云炬创业管理笔记]第三章打造优秀创业团队讨论4
  7. h5实现网页内容跟随窗口大小移动_HTML5 移动页面自适应手机屏幕四类方法
  8. VTK修炼之道63:纹理映射体绘制_二维纹理映射
  9. VTK修炼之道9:坐标系统及空间变换(窗口-视图分割)
  10. 超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大