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 ...
随机推荐
- Java观察者模式(Observer模式)
Java深入到一定程度,就不可避免的碰到设计模式(design pattern)这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广泛,遵循 ...
- html+css学习笔记:实用LessColor函数搭建配色方案
http://www.zcool.com.cn/article/ZMTUyNDc2.html 前言:用LESS CSS框架进行编码会简化代码结构,提高我们的工作效率,但是试验后你会发现,默认情况下,L ...
- jquery学习笔记---Dom操作
一.DOM操作的分类 DOM(document object model)是一种与浏览器.平台.语言无关的接口,使用该接口可以访问页面中的·所有组件.DOM的操作可以分为DOM Core.HTML-D ...
- 图结构练习——最短路径(dijkstra算法(迪杰斯拉特))
图结构练习——最短路径 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 给定一个带权无向图,求节点1到节点n的最短路径. ...
- log4j设置日志格式为UTF-8
想要log4j输出的日志文件的编码格式为UTF-8.正常情况下只需要添加下述的代码即可: log4j.appender.appender_name.Encoding=UTF-8 但是在spring与l ...
- RMAN恢复目录
是否使用RMAN恢复目录(Recovery Catalog 你可能从其他人或书上听过RMAN恢复目录(也有可能是其他名字,RMAN Recovery Catalog的翻译较多较杂,以下简称恢复目录), ...
- 同一天的时间差,显示为HHMMSS和指定日期时间部分
//1.hhmmss private String setGoodsDisBalance(Date startTime,Date endTime){ //时间差:毫秒ms long diff = en ...
- POJ 1947 Rebuilding Roads 树形DP
Rebuilding Roads Description The cows have reconstructed Farmer John's farm, with its N barns (1 & ...
- oc精简笔记
首先如果是想在终端学习的话,以下内容是必须的,如果是直接使用xcode的请随意: operating system os X ter 终端的缩写 ls 显示目录文件 ...
- ios 多文件上传
/** * 上传多个文件 * * @param url 请求接口地址 * @param filedata 文件名称和数据(key:value) * @param btnName 上 ...