题目描述

给定一个长度为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个数大(严格大于,即没有等号)。
请任意构造出一组满足条件的方案,或者判断无解。

输入

第一行包含三个正整数n,s,m(1<=s<=n<=100000,1<=m<=200000)。
接下来s行,每行包含两个正整数p[i],d[i](1<=p[i]<=n,1<=d[i]<=10^9),表示已知a[p[i]]=d[i],保证p[i]递增。
接下来m行,每行一开始为三个正整数l[i],r[i],k[i](1<=l[i]<r[i]<=n,1<=k[i]<=r[i]-l[i]),接下来k[i]个正整数x[1],x[2],...,x[k[i]](l[i]<=x[1]<x[2]<...<x[k[i]]<=r[i]),表示这k[i]个数中的任意一个都比任意一个剩下的r[i]-l[i]+1-k[i]个数大。Σk <= 300,000

输出

若无解,则输出NIE。
否则第一行输出TAK,第二行输出n个正整数,依次输出序列a中每个数。

样例输入

5 2 2
2 7
5 3
1 4 2 2 3
4 5 1 4

样例输出

TAK
1 7 5 4 3


题解

线段树优化建图+差分约束系统+拓扑排序

先想朴素的建图方法:利用差分约束的思想,如果要求x比y大,那么连边y->x,长度为1。对于每条信息,将非给定节点向一个新建节点连边,长度为0;新建节点向所有给定节点连边,长度为1。然后拓扑排序,如果有点没被更新,或者与给定的点权冲突(即要求比给出的大)则无解,否则出解。

这样建图边数爆炸。考虑到每次给出的都是一段区间,所以可以使用线段树优化这个建图过程。

建立线段树,从子节点到父节点连长度为0的边;对于每条信息,把非给定节点分成k+1个区间,每个区间在线段树中找到对应位置,这些位置向新建节点连边,长度为0;新建节点向给定节点对应的叶子结点连边,长度为1。然后拓扑排序即可。

至于拓扑排序求解的方法,需要记录f数组和t数组,分别表示点的权值和点的已知权值,如果遇到一个点存在已知权值,且f>t,则无解,否则f取f与t的max。

另外,“每个数都在1到10^9范围内”这个10^9是有用的,当f值大于10^9时也应算作无解。

#include <cstdio>
#include <cstring>
#include <queue>
#define N 1000010
#define M 3000010
#define lson l , mid , x << 1
#define rson mid + 1 , r , x << 1 | 1
using namespace std;
queue<int> q;
int head[N] , to[M] , len[M] , next[M] , cnt = 1 , tot , p[N] , f[N] , t[N] , x[N] , rd[N];
void add(int x , int y , int z)
{
to[++cnt] = y , len[cnt] = z , next[cnt] = head[x] , head[x] = cnt , rd[y] ++ ;
}
void build(int l , int r , int x)
{
if(l == r)
{
p[l] = x;
return;
}
int mid = (l + r) >> 1;
build(lson) , build(rson);
add(x << 1 , x , 0) , add(x << 1 | 1 , x , 0);
}
void update(int b , int e , int t , int l , int r , int x)
{
if(b <= l && r <= e)
{
add(x , t , 0);
return;
}
int mid = (l + r) >> 1;
if(b <= mid) update(b , e , t , lson);
if(e > mid) update(b , e , t , rson);
}
int main()
{
int n , s , m , i , u , c , d , l , r , k;
scanf("%d%d%d" , &n , &s , &m);
build(1 , n , 1) , tot = 4 * n;
while(s -- ) scanf("%d%d" , &c , &d) , f[p[c]] = t[p[c]] = d;
while(m -- )
{
scanf("%d%d%d" , &l , &r , &k) , x[0] = l - 1 , x[k + 1] = r + 1 , tot ++ ;
for(i = 1 ; i <= k ; i ++ ) scanf("%d" , &x[i]) , add(tot , p[x[i]] , 1);
for(i = 0 ; i <= k ; i ++ ) if(x[i + 1] - x[i] > 1) update(x[i] + 1 , x[i + 1] - 1 , tot , 1 , n , 1);
}
for(i = 1 ; i <= tot ; i ++ )
if(!rd[i])
f[i] = max(f[i] , 1) , q.push(i);
while(!q.empty())
{
u = q.front() , q.pop();
for(i = head[u] ; i ; i = next[i])
{
f[to[i]] = max(f[to[i]] , f[u] + len[i]) , rd[to[i]] -- ;
if(t[to[i]] && f[to[i]] > t[to[i]])
{
printf("NIE\n");
return 0;
}
if(!rd[to[i]]) q.push(to[i]);
}
}
for(i = 1 ; i <= n ; i ++ )
{
if(!f[p[i]] || f[p[i]] > 1000000000)
{
printf("NIE\n");
return 0;
}
}
printf("TAK\n");
for(i = 1 ; i < n ; i ++ ) printf("%d " , f[p[i]]);
printf("%d" , f[p[n]]);
return 0;
}

【bzoj4383】[POI2015]Pustynia 线段树优化建图+差分约束系统+拓扑排序的更多相关文章

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

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

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

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

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

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

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

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

  5. BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan

    Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...

  6. 【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流

    [BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...

  7. 【ARC069F】Flags 2-sat+线段树优化建图+二分

    Description ​ 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离. Input ​ 第一行一个整数 N. ​ 接下来 N 行每行两个整数 xi, ...

  8. 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序

    题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆.  现在 ...

  9. 【bzoj4699】树上的最短路(树剖+线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

随机推荐

  1. Linux OpenGL 实践篇-12-procedural-texturing

    程序式纹理 简单的来说程序式纹理就是用数学公式描述物体表面的纹路 .而实现这个过程的着色器我们称之为程序纹理着色器,通常在这类着色器中我们能使用的输入信息也就是顶点坐标和纹理坐标. 程序式纹理的优点 ...

  2. shell批量转换iOS和Android图标

    icon_ios.sh #!/bin/sh convert icon-1024.png -resize 180x180 icon-180@3x.png convert icon-1024.png -r ...

  3. PHP框架深度解析

    PHP成为世界上最流行的脚本语言有许多原因:灵活性,易用性等等.但通常只用PHP或者其他语言编码就会显得单调.重复,这时候就需要一个PHP框架来代替程序员完成那些重复不变的部分.本文通过回答What, ...

  4. python之道06

    1,使⽤循环打印以结果: * *** ***** ******* ********* 答案: 方法一: for i in range(10): if i % 2 == 1: print(i*'*') ...

  5. Java8新特性Lambda表达式

    List<RoleDO> allRoles = roleService.list(); //获取角色中备注不是app的集合List<RoleDO> webRoles = all ...

  6. 关于“xx.xx已被OS X使用,无法打开”的问题

    Mac电脑上的文件拷贝到移动硬盘,有时候会出现“xx.xx已被OS X使用,无法打开”的问题. 解决办法: 1.打开终端(或在Mac搜索里面输入Terminal); 2.在终端里输入 xattr -l ...

  7. OpenCV2.4.11+VS2012的环境配置+“fatal error LNK1112: 模块计算机类型“X86”与目标计算机类型“x64”冲突”的问题解决

    本来OpenCV环境配置的问题是个基础问题,但是步骤有点小烦,所以几乎每次都要百度一下,加上这次遇到的“fatal error LNK1112: 模块计算机类型“X86”与目标计算机类型“x64”冲突 ...

  8. 常用JS方法整理

    目录: 截取指定字节数的字符串 判断是否微信 获取时间格式的几个举例 获取字符串字节长度 对象克隆.深拷贝 组织结构代码证验证 身份证号验证 js正则为url添加http标识 URL有效性校验方法 自 ...

  9. Python旅途——入门基础

    1.入门 ​ 作为近几年计算机程序设计语言中很火的Python,是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大 ...

  10. MySQL 之Navicat Premium 12安装使用、pymysql模块使用、sql注入问题的产生与解决

    本文内容提要: Navicat Premium 12 的介绍.使用. pymysql模块的使用 sql注入问题的产生与解决 -------------------------------------- ...