BZOJ4369 : [IOI2015]teams分组
将分组计划按照$k$从小到大排序,维护一个单调栈,每个元素为一个矩形,按最底下元素从高到低排列,栈顶最低。
每次加入一个矩形可选区域,维护单调栈,可以往回合并。
然后将所有最低点不满足的矩形取出,合并后放回。
每次考虑栈顶区域,将它取到和下一个矩形底边一致时合并。
可持久化线段树维护,时间复杂度$O((n+s)\log n)$。
#include<cstdio>
#include<algorithm>
const int N=500010,M=200010,P=N*20;
int n,m,k,i,j,x,g[N],v[N],nxt[N],a[M],t;
int val[P],l[P],r[P],tot,T[N];
struct E{int r,l,d,k;E(){}E(int _r,int _l,int _d,int _k){r=_r,l=_l,d=_d,k=_k;}}q[M];
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
int ins(int x,int a,int b,int c){
int y=++tot;val[y]=val[x]+1;
if(a==b)return y;
int mid=(a+b)>>1;
if(c<=mid)l[y]=ins(l[x],a,mid,c),r[y]=r[x];else l[y]=l[x],r[y]=ins(r[x],mid+1,b,c);
return y;
}
int ask(int x,int y,int a,int b,int c,int d){
if(c>d)return 0;
if(c<=a&&b<=d)return val[x]-val[y];
int mid=(a+b)>>1,t=0;
if(c<=mid)t=ask(l[x],l[y],a,mid,c,d);
if(d>mid)t+=ask(r[x],r[y],mid+1,b,c,d);
return t;
}
int low(int x,int y,int a,int b,int c){
if(val[x]==val[y])return 0;
if(a==b)return a;
int mid=(a+b)>>1;
if(c<=mid){
int t=low(l[x],l[y],a,mid,c);
if(t)return t;
}
return low(r[x],r[y],mid+1,b,c);
}
int kth(int x,int y,int c,int k){
k+=ask(x,y,1,n,1,c-1);
int a=1,b=n,mid,t;
while(a<b){
mid=(a+b)>>1;
t=val[l[x]]-val[l[y]];
if(k<=t)x=l[x],y=l[y],b=mid;else k-=t,x=r[x],y=r[y],a=mid+1;
}
return a;
}
inline void merge(){
if(t<2)return;
if(q[t].d>=q[t-1].d){
q[t-1].r=q[t].r;
if(q[t].d==q[t-1].d)q[t-1].k+=q[t].k;
t--;
}
}
inline bool solve(){
read(k);
int sum=0;
for(i=1;i<=k;i++){
read(a[i]);
sum+=a[i];
if(sum>n)return 0;
}
std::sort(a+1,a+k+1);
for(i=1,t=0;i<=k;i++){
int x=a[i],d=low(T[x],T[a[i-1]],1,n,x),l,r=0;
if(d)q[++t]=E(T[x],T[a[i-1]],d,ask(T[x],T[a[i-1]],1,n,d,d)),merge();
while(t&&q[t].d<x){
if(!r)r=q[t].r;
l=q[t--].l;
}
if(r){
d=low(r,l,1,n,x);
if(d)q[++t]=E(r,l,d,ask(r,l,1,n,d,d)),merge();
}
while(x){
if(!t)return 0;
if(t==1){
int now=ask(q[t].r,q[t].l,1,n,q[t].d+1,n)+q[t].k;
if(now<x)return 0;
if(now==x)t--;
else if(q[t].k>x)q[t].k-=x;
else if(q[t].k==x){
q[t].d=low(q[t].r,q[t].l,1,n,q[t].d+1);
q[t].k=ask(q[t].r,q[t].l,1,n,q[t].d,q[t].d);
}else{
x-=q[t].k;
int d=kth(q[t].r,q[t].l,q[t].d+1,x);
int tmp=ask(q[t].r,q[t].l,1,n,q[t].d+1,d-1);
x-=tmp;
int k=ask(q[t].r,q[t].l,1,n,d,d);
if(x<k){
q[t].d=d;
q[t].k=k-x;
}else{
q[t].d=low(q[t].r,q[t].l,1,n,d+1);
q[t].k=ask(q[t].r,q[t].l,1,n,q[t].d,q[t].d);
}
}
break;
}
int now=ask(q[t].r,q[t].l,1,n,q[t].d+1,q[t-1].d-1)+q[t].k;
if(now<=x){
x-=now;
q[t-1].r=q[t].r;
q[t-1].k+=ask(q[t].r,q[t].l,1,n,q[t-1].d,q[t-1].d);
t--;
}else{
if(q[t].k>x)q[t].k-=x;
else if(q[t].k==x){
q[t].d=low(q[t].r,q[t].l,1,n,q[t].d+1);
q[t].k=ask(q[t].r,q[t].l,1,n,q[t].d,q[t].d);
}else{
x-=q[t].k;
int d=kth(q[t].r,q[t].l,q[t].d+1,x);
int tmp=ask(q[t].r,q[t].l,1,n,q[t].d+1,d-1);
x-=tmp;
int k=ask(q[t].r,q[t].l,1,n,d,d);
if(x<k){
q[t].d=d;
q[t].k=k-x;
}else{
q[t].d=low(q[t].r,q[t].l,1,n,d+1);
q[t].k=ask(q[t].r,q[t].l,1,n,q[t].d,q[t].d);
}
}
break;
}
}
}
return 1;
}
int main(){
read(n);
for(i=1;i<=n;i++)read(x),read(v[i]),nxt[i]=g[x],g[x]=i;
for(i=1;i<=n;i++)for(T[i]=T[i-1],j=g[i];j;j=nxt[j])T[i]=ins(T[i],1,n,v[j]);
read(m);
while(m--)puts(solve()?"1":"0");
return 0;
}
BZOJ4369 : [IOI2015]teams分组的更多相关文章
- BZOJ 4369: [IOI2015]teams分组
把一个人看成二维平面上的一个点,把一个K[i]看成左上角为(0,+max),右下角为(K[i],K[i])的一个矩阵,那么可以很好地描述人对于询问是否合法(我也不知道他怎么想到这东西的) 然后把一组询 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- jquery.autocomplete 模糊查询 支持分组
//demo <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <lin ...
- CBQW ---分组表单展示
工作流审核表单后,将表单信息展示页面中. Rest读取展示 展示方式有2 一. CBQW内容查询, 通过CBQW内容查询.分别通过设置itemstyle和header xsl ...
- MySQL最常用分组聚合函数
一.聚合函数(aggregation function)---也就是组函数 在一个行的集合(一组行)上进行操作,对每个组给一个结果. 常用的组函数: AVG([distinct] expr) 求平均值 ...
- 【CF1133E】K Balanced Teams(动态规划,单调队列)
[CF1133E]K Balanced Teams(动态规划,单调队列) 题面 CF 让你把一堆数选一些出来分成不超过\(K\)组,每一组里面的最大值和最小值之差不超过\(5\),求最多有多少个人元素 ...
- CF899A Splitting in Teams
CF899A Splitting in Teams 题意翻译 n个数,只有1,2,把它们任意分组,和为3的组最多多少 题目描述 There were nn groups of students whi ...
- Yet Another Division Into Teams
E. Yet Another Division Into Teams 首先要想明白一个东西,就是当一个小组达到六个人的时候,它一定可以拆分成两个更优的小组. 这个题可以用动态规划来写,用一个数组来保存 ...
- CodeForces 1249A --- Yet Another Dividing into Teams
[CodeForces 1249A --- Yet Another Dividing into Teams] Description You are a coach of a group consis ...
随机推荐
- iPhone:4.7 5.5 4 3.5 对应的各个设备屏幕尺寸对应的像素及App上线信息
Shared App Information You can access these properties from the App Details page in the App Informat ...
- sql语句的join用法
sql的join分为三种,内连接.外连接.交叉连接. 以下先建2张表,插入一些数据,后续理解起来更方便一些. create table emp(empno int, name char(20),dep ...
- Javascript和Java获取各种form表单信息的简单实例
大家都知道我们在提交form的时候用了多种input表单.可是不是每一种input表单都是很简单的用Document.getElementById的方式就可以获取到的.有一些组合的form类似于che ...
- Redis笔记(五)Redis的事务
>>关系型数据库的事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消. Atomic(原子性): 一个事务(transaction)中的 ...
- OS Boot Loader -- 启动器
这篇文章先抛出来,现在还没有彻底研究明白,但可以做个个人的小结和整理: 记得刚开始搞Linux的时候,普遍采用的是grub,后来有了grub2,尤其是在ubuntu那种非常差劲的不稳定的更新频繁的系统 ...
- Chrome Crx 插件下载
扯蛋的GFW屏蔽了google域导致下载Chrome插件加载失败,本人想收集以些chrome的Crx插件,可供直接下载 XMarks - 在不同电脑不同浏览器之间同步书签 下载地址: http:/ ...
- Pyqt phonon的使用
本文是用Pyqt实现了下网上一个Qt版大牛关于phonon的介绍 Qt phonon地址:http://wenku.baidu.com/link?url=nH_dZ8lZbXHy8N5__8jAWLX ...
- [LeetCode] Length of Last Word
Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the l ...
- js 上传文件后缀名的判断 var flag=false;应用
js 上传文件后缀名的判断 var flag=false;应用 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// ...
- 2-06使用SQL语句创建数据库3
向现有数据库中添加文件组和数据文件几种方式以及步骤: 第一种:在视图下添加文件组和数据文件. 添加文件组的步骤: 右击你想要添加文件组的数据库点属性,然后点文件组就可以添加. 添加数据文件的步骤: 下 ...