给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r-1],a[r]里这k个数中的任意一个都比任意一个剩下的r-l+1-k个数大(严格大于,即没有等号)。请任意构造出一组满足条件的方案,或者判断无解。

Solution

这个模型有点像差分约束系统,但是建图复杂度过高。

考虑到每次一个区间内的k个数将整段序列划分为k+1个区间,所以我们考虑用线段树优化这个过程,每次建一个s点和这k个点连边,再和剩下的数所对应的区间连边,这样就保证了我们建图的复杂度。

然后题目中给的数域是1-1e9,有两种方法,一种是从极小向大里跑,另一种是从极大往小里跑。

如果是前一种,那么我的转移顺序必须为从小到大,回顾我们的连边,发现需要从一堆区间向S走,但是这一堆区间需要下面的节点转移而来,所以我们在线段树上连边的方式为从下往上连。

后一种反之。

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define N 400002
#define M 4000003
using namespace std;
queue<int>q;
int head[N],tot,du[N],ji[N],anti_ji[N],top,rs[N],ls[N],s,n,m,pos,ss,x,a[N],l,r,k,num[N],tag;
struct node{
int n,to,l;
}e[M];
inline void add(int u,int v,int l){
e[++tot].n=head[u];
e[tot].to=v;
e[tot].l=l;du[v]++;
head[u]=tot;
}
void build(int cnt,int l,int r){
if(l==r){ji[l]=cnt;anti_ji[cnt]=l;return;}
int mid=(l+r)>>;
ls[cnt]=++top;rs[cnt]=++top;
add(ls[cnt],cnt,);add(rs[cnt],cnt,);
build(ls[cnt],l,mid);build(rs[cnt],mid+,r);
}
void query(int cnt,int l,int r,int L,int R){
if(l>=L&&r<=R){
add(cnt,s,);
return;
}
int mid=(l+r)>>;
if(mid>=L)query(ls[cnt],l,mid,L,R);
if(mid<R)query(rs[cnt],mid+,r,L,R);
}
int main(){
top=;
scanf("%d%d%d",&n,&ss,&m);
for(int i=;i<=ss;++i)scanf("%d%d",&pos,&x),a[pos]=x;
build(,,n);
for(int i=;i<=m;++i){
scanf("%d%d%d",&l,&r,&k);int p=l;s=++top;
for(int j=;j<=k;++j){
scanf("%d",&x);add(s,ji[x],);
if(x>p)query(,,n,p,x-);
p=x+;
}
if(p<=r)query(,,n,p,r);
}
for(int i=;i<=top;++i){
if(!du[i])q.push(i),num[i]=;
if(a[anti_ji[i]])num[i]=a[anti_ji[i]];
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=e[i].n){
int v=e[i].to,x=num[u]+e[i].l;
if(!--du[v])q.push(v);
if(!a[anti_ji[v]]){
num[v]=max(num[v],x);
}
else{
num[v]=a[anti_ji[v]];
if(a[anti_ji[v]]<x)tag=;
}
}
}
for(int i=;i<=top;++i)if(du[i])tag=;
for(int i=;i<=n;++i)if(num[ji[i]]>1e9||!num[ji[i]])tag=;
if(tag){
printf("NIE\n");
return ;
}
printf("TAK\n");
for(int i=;i<=n;++i)printf("%d ",num[ji[i]]);
return ;
}

Code2

#include<iostream>
#include<cstdio>
#include<queue>
#define N 400002
#define M 4000003
using namespace std;
queue<int>q;
int head[N],tot,du[N],ji[N],anti_ji[N],top,rs[N],ls[N],s,n,m,pos,ss,x,a[N],l,r,k,num[N],tag;
struct node{
int n,to,l;
}e[M];
inline void add(int u,int v,int l){
e[++tot].n=head[u];
e[tot].to=v;
e[tot].l=l;du[v]++;
head[u]=tot;
}
void build(int cnt,int l,int r){
if(l==r){ji[l]=cnt;anti_ji[cnt]=l;return;}
int mid=(l+r)>>;
ls[cnt]=++top;rs[cnt]=++top;
add(cnt,ls[cnt],);add(cnt,rs[cnt,);
build(ls[cnt],l,mid);build(rs[cnt],mid+,r);
}
void query(int cnt,int l,int r,int L,int R){
if(l>=L&&r<=R){
add(s,cnt,);
return;
}
int mid=(l+r)>>;
if(mid>=L)query(ls[cnt],l,mid,L,R);
if(mid<R)query(rs[cnt],mid+,r,L,R);
}
int main(){
top=;
scanf("%d%d%d",&n,&ss,&m);
for(int i=;i<=ss;++i)scanf("%d%d",&pos,&x),a[pos]=x;
build(,,n);
for(int i=;i<=m;++i){
scanf("%d%d%d",&l,&r,&k);int p=l;s=++top;
for(int j=;j<=k;++j){
scanf("%d",&x);add(ji[x],s,);
if(x>p)query(,,n,p,x-);
p=x+;
}
if(p<=r)query(,,n,p,r);
}
for(int i=;i<=top;++i){
if(!du[i])q.push(i);
num[i]=1e9;
}
while(!q.empty()){
int u=q.front();q.pop();if(anti_ji[u]&&!num[u])num[u]=1e9;
for(int i=head[u];i;i=e[i].n){
int v=e[i].to,x=num[u]-e[i].l;
if(!--du[v])q.push(v);
if(!a[anti_ji[v]]){
num[v]=min(num[v],x);
}
else{
num[v]=a[anti_ji[v]];
if(a[anti_ji[v]]>x)tag=;
}
}
}
for(int i=;i<=top;++i)if(du[i])tag=;
if(tag){
printf("NIE\n");
return ;
}
printf("TAK\n");
for(int i=;i<=n;++i)printf("%d ",num[ji[i]]);
return ;
}

bzoj4383(拓扑排序)的更多相关文章

  1. BZOJ4383 Pustynia(线段树+拓扑排序)

    线段树优化建图暴力拓扑排序即可.对于已确定的数,拓扑排序时dp,每个节点都尽量取最大值,如果仍与已确定值矛盾则无解.叶子连出的边表示大于号,其余边表示大于等于. #include<iostrea ...

  2. [POI2015][bzoj4383] Pustynia [线段树优化建图+拓扑排序]

    题面 bzoj权限题传送门 luogu传送门 思路 首先,这个题目显然可以从所有小的点往大的连边,然后如果没环就一定可行,从起点(入读为0)开始构造就好了 但是问题来了,如果每个都连的话,本题中边数是 ...

  3. 【bzoj4383】[POI2015]Pustynia 线段树优化建图+差分约束系统+拓扑排序

    题目描述 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r- ...

  4. BZOJ4383 [POI2015]Pustynia[线段树优化建边+拓扑排序+差分约束]

    收获挺大的一道题. 这里的限制大小可以做差分约束,从$y\to x$连$1$,表示$y\le x-1$即$y<x$,然后跑最长路求解. 但是,如果这样每次$k+1$个小区间每个点都向$k$个断点 ...

  5. bzoj4383 [POI2015]Pustynia 拓扑排序+差分约束+线段树优化建图

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4383 题解 暴力的做法显然是把所有的条件拆分以后暴力建一条有向边表示小于关系. 因为不存在零环 ...

  6. 算法与数据结构(七) AOV网的拓扑排序

    今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...

  7. 有向无环图的应用—AOV网 和 拓扑排序

    有向无环图:无环的有向图,简称 DAG (Directed Acycline Graph) 图. 一个有向图的生成树是一个有向树,一个非连通有向图的若干强连通分量生成若干有向树,这些有向数形成生成森林 ...

  8. 【BZOJ-2938】病毒 Trie图 + 拓扑排序

    2938: [Poi2000]病毒 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 609  Solved: 318[Submit][Status][Di ...

  9. BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...

随机推荐

  1. babel (二) update to v7

    一.rootmode In 7.1, we've introduced a rootMode option for further lookup if necessary. 二.Remove prop ...

  2. js 深度复制deepClone

    function isObject(obj) { return typeof obj === 'object' && obj != null; } const deepClone =( ...

  3. 1 Expression of Possiblity

    Expression of possibility Probably     Perhaps There's a change(that) It's very likly(that) It's pos ...

  4. UTC时间、GMT时间、本地时间、Unix时间戳

    引用: https://blog.csdn.net/u012102306/article/details/51538574 https://blog.csdn.net/foxir/article/de ...

  5. Laravel 5.2+ 使用url()全局函数返回前一个页面的地址

    注意:文章标题中5.2+表示该文章内容可向上兼容,适用于Laravel版本5.2及更高(目前最新为5.6),但不可向下兼容,即不适用于5.2版本以下.推荐大家花一点点时间,将自己的Laravel更新至 ...

  6. Day5-1 面向对象和面向过程

    摘要: 类的定义 类的增删改查 对象的增删改查 对象的查找和绑定 面向对象和面向过程的区别: 1.面向过程就像是工厂的流水线,按部就班的有序的工作. 优点:把复杂的问题简单化 缺点:可扩展性差.一个步 ...

  7. C# Note16: wpf window 中添加enter和双击事件

     一.添加回车(enter)事件 在C#编程时,有时希望通过按回车键,控件焦点就会自动从一个控件跳转到下一个控件进行操作. 以用户登录为例,当输入完用户名和密码后, 需要点击登录按钮,而登录按钮必须获 ...

  8. python[练习题]:实现Base64编码

    要求自己实现算法,不用库. Base64简介: Base64是一种用64个字符来表示任意二进制数据的方法. 用记事本打开exe.jpg.pdf这些文件时,我们都会看到一大堆乱码,因为二进制文件包含很多 ...

  9. Laravel 出现 No application encryption key has been specified.

    若文件根目录下没有 .env 1..env.example 改名使用命令 copy 修改为 .env 2.使用命令 php artisan key:generate  获取密码,自动保存到 .env3 ...

  10. 使用阿里云OSS,上传图片时报错:java.lang.ClassNotFoundException:org.apache.http.ssl.TrustStrategy

    问题产生的原因就是jar包版本问题,阿里的SDk引入的pom中依赖的httpclient和httpcore版本高于当前项目中已经设置的版本. 解决: 删除低版本后,更新下项目.