BZOJ4383 [POI2015]Pustynia[线段树优化建边+拓扑排序+差分约束]
收获挺大的一道题。
这里的限制大小可以做差分约束,从$y\to x$连$1$,表示$y\le x-1$即$y<x$,然后跑最长路求解。
但是,如果这样每次$k+1$个小区间每个点都向$k$个断点连边显然爆炸。。考虑优化建边。
发现这里是每个小区间各点连边,所以可以线段树优化,不过每个小区间都要向$k$个点连边还是爆炸,这时候,考虑一种类似于线段树建边里面区间向区间的连边方式:这一边的各个拆分的小区间向一个虚点连边,这个虚点再向另一个区间拆分的小区间连边,保证了边数=区间数=$\log$级别。那这里也类似,只要把$k+1$小段每一段的拆分区间全连上虚点,然后虚点连向$k$个点就行了,本质还是线段树建边的类比。由于保证了$\sum k$,所以边数在$\sum k\log n$级别。
然后,这样一张图是和原图等价的,这时我们要做一个差分约束的求解。不过,注意到,只要这里面出现了环,那肯定是正环(因为线段树图和原图等价,原图全是$1$边),肯定就无解。如果没有环,那么就是个DAG,这时我们并不用很蠢的跑spfa(因为容易被卡,比如说链),直接拓扑排序更新max就行了。最后注意一下不合法(超过$1e9$或超过原来给定值)就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define mst(x) memset(x,0,sizeof x)
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=1e5+;
int org[N],val[N<<],deg[N<<];
int n,s,m,cnt,res;
struct thxorz{
int head[N<<],nxt[N*],to[N*],tot;
bool w[N*];
inline void add(int x,int y,int z){to[++tot]=y,nxt[tot]=head[x],head[x]=tot,w[tot]=z,++deg[y];}
}G;
struct SGT{
int id[N<<];
#define lc i<<1
#define rc i<<1|1
void build(int i,int L,int R){
if(L==R){id[i]=L;return;}
int mid=L+R>>;id[i]=++cnt;
build(lc,L,mid),build(rc,mid+,R);
G.add(id[lc],id[i],),G.add(id[rc],id[i],);
}
void update(int i,int L,int R,int ql,int qr){
if(ql<=L&&qr>=R){G.add(id[i],cnt,);return;}
int mid=L+R>>;
if(ql<=mid)update(lc,L,mid,ql,qr);
if(qr>mid)update(rc,mid+,R,ql,qr);
}
}T;
queue<int> q;
#define y G.to[j]
inline void topo(){
for(register int i=;i<=n;++i)if(!deg[i])q.push(i);//dbg(i);
while(!q.empty()){
int x=q.front();q.pop();++res;
for(register int j=G.head[x];j;j=G.nxt[j]){
MAX(val[y],val[x]+G.w[j]);//mistake
if(!(--deg[y]))q.push(y);
}
}
}
#undef y
int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
cnt=read(n),read(s),read(m);
fill(val+,val+n+n+m+,);
for(register int i=,x;i<=s;++i)read(x),val[x]=read(org[x]);
T.build(,,n);
for(register int i=,l,r,k;i<=m;++i){
read(l),read(r),read(k);++cnt;
for(register int j=,x,las=l-;j<=k;++j,las=x){
read(x);G.add(cnt,x,);
if(las+<x)T.update(,,n,las+,x-);
if(j==k&&x<r)T.update(,,n,x+,r);
}
}
topo();
if(res<cnt){puts("NIE");return ;}
for(register int i=;i<=n;++i)if(val[i]>1e9||org[i]&&val[i]>org[i]){puts("NIE");return ;}
puts("TAK");
for(register int i=;i<=n;++i)printf("%d%c",val[i]," \n"[i==n]);
return ;
}
这题给了我一点启示。。
首先,区间连边,铁定是要线段树优化的。。只是有时候可能并不是那么显然,所以就要靠改造。。
然后,这个差分约束求解,并不是非要跑spfa的,如果原图是DAG,可以拓扑,这一点再拓展一下,就可以线性求全正权图的差分约束了,update了一下这篇。BZOJ2330 糖果[差分约束方案+spfa?/tarjan]
BZOJ4383 [POI2015]Pustynia[线段树优化建边+拓扑排序+差分约束]的更多相关文章
- BZOJ_4383_[POI2015]Pustynia_线段树优化建图+拓扑排序
BZOJ_4383_[POI2015]Pustynia_线段树优化建图+拓扑排序 Description 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息 ...
- [POI2015][bzoj4383] Pustynia [线段树优化建图+拓扑排序]
题面 bzoj权限题传送门 luogu传送门 思路 首先,这个题目显然可以从所有小的点往大的连边,然后如果没环就一定可行,从起点(入读为0)开始构造就好了 但是问题来了,如果每个都连的话,本题中边数是 ...
- 【bzoj4383】[POI2015]Pustynia 线段树优化建图+差分约束系统+拓扑排序
题目描述 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r- ...
- 牛客多校第四场 J.Hash Function(线段树优化建图+拓扑排序)
题目传送门:https://www.nowcoder.com/acm/contest/142/J 题意:给一个hash table,求出字典序最小的插入序列,或者判断不合法. 分析: eg.对于序列{ ...
- [POI2015]PUS [线段树优化建图]
problem 线段树优化建图,拓扑,没了. #include <bits/stdc++.h> #define ls(x) ch[x][0] #define rs(x) ch[x][1] ...
- [bzoj5017][Snoi2017]炸弹 tarjan缩点+线段树优化建图+拓扑
5017: [Snoi2017]炸弹 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 608 Solved: 190[Submit][Status][ ...
- BZOJ 5496: [2019省队联测]字符串问题 (后缀数组+主席树优化建图+拓扑排序)
题意 略 分析 考场上写了暴力建图40分溜了-(结果只得了30分) 然后只要优化建边就行了 首先给出的支配关系无法优化,就直接A向它支配的B连边. 考虑B向以B作为前缀的所有A连边,做一遍后缀数组,两 ...
- 洛谷P3588 [POI2015]PUS(线段树优化建图)
题面 传送门 题解 先考虑暴力怎么做,我们把所有\(r-l+1-k\)中的点向\(x\)连有向边,表示\(x\)必须比它们大,那么如果这张图有环显然就无解了,否则的话我们跑一个多源最短路,每个点的\( ...
- bzoj4383 [POI2015]Pustynia 拓扑排序+差分约束+线段树优化建图
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4383 题解 暴力的做法显然是把所有的条件拆分以后暴力建一条有向边表示小于关系. 因为不存在零环 ...
随机推荐
- eNSP——配置通过FTP进行文件操作
原理: FTP (File Transfer Protocol,文件传输协议)是在TCP/IP网络和Internet.上最早使用的协议之-,在TCP/IP协议族中属于应用层协议,是文件传输的Inter ...
- flask核心对象
appcontext 上下文 处理
- Nginx 小入门记录 之 Nginx 配置文件解读(二)
上一小节主要是记录一些环境准备和Nginx的安装,接下来对Nginx基本配置进行记录. 查看配置文件安装记录 可以通过以下Linux命令进行查看: rpm -ql nginx rpm 是liunx的包 ...
- mysql的密码规则问题
今天在设置mysql某用户的密码时,出现了此报错: ERROR 1819 (HY000) Your password does not satisfy the current policy req ...
- docker国内镜像加速
在/etc/docker/daemon.json中添加内容: { "registry-mirrors": ["https://registry.docker-cn.c ...
- C++11 thread condition_variable mutex 综合使用
#include <mutex> #include <condition_variable> #include <chrono> #include <thre ...
- PTA(Advanced Level)1037.Magic Coupon
The magic shop in Mars is offering some magic coupons. Each coupon has an integer N printed on it, m ...
- Java内存管理-探索Java中字符串String(十二)
做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 一.初识String类 首先JDK API的介绍: public final class String extends O ...
- 安川机器人Yaskawa
安川机器人自动回原点 1. 判断机器人是否在安全位置 (立方体干涉区) 2. 读取机器人当前位置 GETS PX000 $PX001 读取基座标下的机器人当前位置并放到位置型变量P000中 $P ...
- 如何给Swagger加注释
在Startup.cs文件中的ConfigureServices()方法中添加如下代码即可 services.AddSwaggerGen(options => { options.Swagger ...