收获挺大的一道题。


这里的限制大小可以做差分约束,从$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[线段树优化建边+拓扑排序+差分约束]的更多相关文章

  1. BZOJ_4383_[POI2015]Pustynia_线段树优化建图+拓扑排序

    BZOJ_4383_[POI2015]Pustynia_线段树优化建图+拓扑排序 Description 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息 ...

  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. 牛客多校第四场 J.Hash Function(线段树优化建图+拓扑排序)

    题目传送门:https://www.nowcoder.com/acm/contest/142/J 题意:给一个hash table,求出字典序最小的插入序列,或者判断不合法. 分析: eg.对于序列{ ...

  5. [POI2015]PUS [线段树优化建图]

    problem 线段树优化建图,拓扑,没了. #include <bits/stdc++.h> #define ls(x) ch[x][0] #define rs(x) ch[x][1] ...

  6. [bzoj5017][Snoi2017]炸弹 tarjan缩点+线段树优化建图+拓扑

    5017: [Snoi2017]炸弹 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 608  Solved: 190[Submit][Status][ ...

  7. BZOJ 5496: [2019省队联测]字符串问题 (后缀数组+主席树优化建图+拓扑排序)

    题意 略 分析 考场上写了暴力建图40分溜了-(结果只得了30分) 然后只要优化建边就行了 首先给出的支配关系无法优化,就直接A向它支配的B连边. 考虑B向以B作为前缀的所有A连边,做一遍后缀数组,两 ...

  8. 洛谷P3588 [POI2015]PUS(线段树优化建图)

    题面 传送门 题解 先考虑暴力怎么做,我们把所有\(r-l+1-k\)中的点向\(x\)连有向边,表示\(x\)必须比它们大,那么如果这张图有环显然就无解了,否则的话我们跑一个多源最短路,每个点的\( ...

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

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

随机推荐

  1. oracle-function-into时为null报错

    oracle-function-into时为null报错 create or replace function P_ADD_CUSTOMER_FOR_CSS_heyt_test(i_cust_name ...

  2. Linux IO模式以及select poll epoll详解

    一 背景 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network ...

  3. class CAdoInterface

    AdoInterface.h #pragma once //#pragma warning (push) //以防会产生警告 C4018,但这个警告是没关系的,所以使用下一句代码屏蔽它 //#prag ...

  4. 剑指offer14:输入一个链表,输出该链表中倒数第k个结点。

    1. 题目描述 输入一个链表,输出该链表中倒数第k个结点. 2. 思路和方法 可以用两个指针,一个指针遍历到第k个结点的时候,第二个指针再走到第一个节点,然后两个指针的距离始终保持k-1.这样,当第一 ...

  5. Python中的幽灵—编码方式

    首先要搞懂本地操作系统编码与系统编码的区别: 本地操作系统编码方式与操作系统有关,Linux默认编码方式为utf-8,Windows默认编码方式为gbk: 系统编码方式与编译器or解释器有关,Pyth ...

  6. xtrabackup原理,整库,单表,部分备份恢复

    物理备份xtrabackup原理 Percona XtraBackup(简称PXB)是 Percona 公司开发的一个用于 MySQL 数据库物理热备的备份工具,支持 MySQl(Oracle).Pe ...

  7. 什么是Sprint?

    Sprint指Scrum团队完成一定数量工作所需的短暂.固定的周期.Sprint是Scrum和敏捷的核心,找到正确的Sprint周期将帮助您的敏捷团队交付更高质量的产品. “在Scrum框架中,庞大且 ...

  8. el-table 单元格样式修改

    <el-table :cell-style="set_cell_style"> set_cell_style({row, column, rowIndex, colum ...

  9. 谈谈对Spring IOC的理解(转发)

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  10. 缩放动画(ScaleTransform)

    在Silverlight的动画框架中,ScaleTransform类提供了在二维空间中的坐标内进行缩放操作,通过ScaleTransform可以在水平或垂直方向的缩放和拉伸对象,以实现一个简单的缩放动 ...