@description@

给定一个长度为 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 个数大(严格大于,即没有等号)。

请任意构造出一组满足条件的方案,或者判断无解。

input

第一行包含三个正整数 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

output

若无解,则输出NIE。

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

sample input

5 2 2

2 7

5 3

1 4 2 2 3

4 5 1 4

sample output

TAK

6 7 1000000000 6 3

@solution@

首先不考虑任何时间会炸空间会炸等种种问题,这是一道差分约束题。

然后我们来优化一下。

其一是建图的时候,边的数量过多这一问题,我们使用线段树来优化建图。

其二则是数据太大跑最短路跑不过的问题。我们根据图的特殊性来优化。

对于我们建出的图,会产生两类环:

第一类是源点连入某个点再由这个点连回来的情况,含义是一个数的上下界。

这种情况,我们可以仅保留它的下界(或者是上界,看差分约束的具体实现方法),事后再来判断它的上界是否合法。

第二类是不经过源点的环,这个环必然无解(因为它表示 a > b > c > ... > a,而这显然是不可能的)。

综上,我们可以将这个图改成无环的图。

然后就可以拓扑排序了。

@accepted code@

为了防止它溢出,我判断上界 10^9 是在拓扑排序里面判断的。

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 100000;
const int MAXM = 200000;
const int MAXK = 300000;
const int MAXV = 4*MAXN + MAXK;
const int INF = int(1E9);
struct edge{
int to, dis;
edge *nxt;
}edges[20*MAXK + 10*MAXN + 5], *adj[MAXV + 5], *ecnt=&edges[0];
void addedge(int u, int v, int w) {
edge *p = (++ecnt);
p->to = v, p->dis = w, p->nxt = adj[u], adj[u] = p;
//printf("(%d %d %d)\n", u, v, w);
}
int id[MAXN + 5], num[4*MAXN + 5], cnt;
void build_segtree(int x, int l, int r) {
num[x] = (++cnt);
if( l == r ) {
id[l] = num[x];
return ;
}
int mid = (l + r) >> 1;
build_segtree(x<<1, l, mid);
addedge(num[x<<1], num[x], 0);
build_segtree(x<<1|1, mid + 1, r);
addedge(num[x<<1|1], num[x], 0);
}
void build_edge_segment(int x, int l, int r, int pl, int pr, int p) {
if( pl <= l && r <= pr ) {
addedge(num[x], p, 0);
return ;
}
if( pl > r || pr < l )
return ;
int mid = (l + r) >> 1;
build_edge_segment(x<<1, l, mid, pl, pr, p);
build_edge_segment(x<<1|1, mid + 1, r, pl, pr, p);
}
int x[MAXN + 5], key[MAXN + 5], n;
int ind[MAXV + 5], dis[MAXV + 5], stk[MAXV + 5], tp;
void solve() {
for(int i=0;i<=cnt;i++) {
for(edge *p=adj[i];p;p=p->nxt)
ind[p->to]++;
dis[i] = INF;
}
dis[0] = 0; stk[++tp] = 0;
while( tp ) {
int t = stk[tp--];
for(edge *p=adj[t];p;p=p->nxt) {
dis[p->to] = min(dis[p->to], dis[t] + p->dis);
if( dis[p->to] < -INF ) {
puts("NIE");
return ;
}
ind[p->to]--;
if( ind[p->to] == 0 ) stk[++tp] = p->to;
}
}
for(int i=0;i<=cnt;i++)
if( ind[i] ) {
puts("NIE");
return ;
}
for(int i=1;i<=n;i++)
if( key[i] != -1 && key[i] + dis[id[i]] ) {
puts("NIE");
return ;
}
puts("TAK");
for(int i=1;i<=n;i++)
printf("%d%c", -dis[id[i]], (i == n) ? '\n' : ' ');
}
int main() {
int s, m;
scanf("%d%d%d", &n, &s, &m);
build_segtree(1, 1, n);
for(int i=1;i<=n;i++) {
addedge(0, id[i], -1);
key[i] = -1;
}
for(int i=1;i<=s;i++) {
int p, d; scanf("%d%d", &p, &d);
addedge(0, id[p], -d);
key[p] = d;
}
for(int i=1;i<=m;i++) {
int l, r, k; cnt++;
scanf("%d%d%d", &l, &r, &k);
x[0] = l - 1, x[k + 1] = r + 1;
for(int j=1;j<=k;j++) scanf("%d", &x[j]);
for(int j=1;j<=k+1;j++) build_edge_segment(1, 1, n, x[j-1] + 1, x[j] - 1, cnt);
for(int j=1;j<=k;j++) addedge(cnt, id[x[j]], -1);
}
solve();
}

@details@

什么?题目中还要求了它不能超过 10^9?

我一开始并没有看到 QAQ。调了好久啊 QAQ。

@bzoj - 4378@ [POI2015] Pustynia的更多相关文章

  1. bzoj 4383: [POI2015]Pustynia

    复习了一下线段树优化建图的姿势,在线段树上连边跑拓扑排序 这题竟然卡vector……丧病 #include <bits/stdc++.h> #define N 1810000 using ...

  2. bzoj 4378: [POI2015]Logistyka ——树桩数组+离散化

    Description 维护一个长度为n的序列,一开始都是0,支持以下两种操作:1.U k a 将序列中第k个数修改为a.2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1,询问能否进行 ...

  3. @bzoj - 4378@ [POI2015] Logistyka

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 维护一个长度为 n 的序列,一开始都是 0,支持以下两种操作: ...

  4. [POI2015]Pustynia

    [POI2015]Pustynia 题目大意: 给定一个长度为\(n(n\le10^5)\)的正整数序列\(a\),每个数都在\(1\)到\(10^9\)范围内,告诉你其中\(s\)个数,并给出\(m ...

  5. 【BZOJ4383】[POI2015]Pustynia 线段树优化建图

    [BZOJ4383][POI2015]Pustynia Description 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r ...

  6. 洛谷P3588 - [POI2015]Pustynia

    Portal Description 给定一个长度为\(n(n\leq10^5)\)的正整数序列\(\{a_n\}\),每个数都在\([1,10^9]\)范围内,告诉你其中\(s\)个数,并给出\(m ...

  7. bzoj 4386: [POI2015]Wycieczki

    bzoj 4386: [POI2015]Wycieczki 这题什么素质,爆long long就算了,连int128都爆……最后还是用long double卡过的……而且可能是我本身自带大常数吧,T了 ...

  8. BZOJ 4385: [POI2015]Wilcze doły

    4385: [POI2015]Wilcze doły Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 648  Solved: 263[Submit][ ...

  9. BZOJ 4384: [POI2015]Trzy wieże

    4384: [POI2015]Trzy wieże Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 217  Solved: 61[Submit][St ...

随机推荐

  1. eclipse 代码格式化快捷键CTRL SHIFT F无反应的解决办法

    基本上就是被其他软件占用了,比如输入法的简繁体切换,改其他软件,保留eclipse就好

  2. 洛谷 P1004 方格取数 【多线程DP/四维DP/】

    题目描述(https://www.luogu.org/problemnew/show/1004) 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0. ...

  3. 前端--HTML简介

    软件开发架构: c/s架构 客户端 服务端 b/s架构 浏览器 服务端 本质:b/s架构也是c/s架构 HTTP协议 超文本传输协议:规定了客户端与服务端之间消息传输的格式 四个特性: 1.基于TCP ...

  4. SVG 动态添加元素与事件

    SVG文件是由各个元素组成.元素由标签定义,而标签格式即html的元素定义格式.但是载入一个SVG文件,却无法通过常规的js获取对象方式来获取到SVG中定义的元素,更无法通过这种方式来动态添加SVG元 ...

  5. CentOS 6.8 Java 环境搭建

      1.搜索 Java 1.7 64 2.下载 文件 3.Xshell 安装lrzsz 4.选择路径 5.使用 rz 命令选择上传 6.打开 /etc/profile vim /etc/profile ...

  6. linux设置变量的三种方法

    1在/etc/profile文件中添加变量对所有用户生效(永久的) 用VI在文件/etc/profile文件中增加变量,该变量将会对Linux下所有用户有效,并且是“永久生效”. 例如:编辑/etc/ ...

  7. 如何查看MySQL执行计划呢?

    覆盖索引: MySQL可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件 包含所有满足查询需要的数据的索引称为 覆盖索引(Covering Index) 如果要使用覆盖索引,一定 ...

  8. WCF 无管理员权限下启用服务

    1 使用 netsh.exe 工具 C:\Windows\system32>netsh http add urlacl url=http://+:8733/WcfServiceLibrary1 ...

  9. 一位AI研究员+区块链创业者的终极展望:AI DAO将统治世界

    一位AI研究员+区块链创业者的终极展望:AI DAO将统治世界 [日期:2017-01-09] 来源:infoq.com  作者:杨赛 [字体:大 中 小] Trent McConaghy是一位资深的 ...

  10. 在一个已经使用mybatis的项目里引入mybatis-plus,结果不能共存

    mybatis-plus版本号:3.0.6 问题产生原因: 原有的项目使用的是springboot+mybatis的框架,一切接口服务均没有问题.由于新的需求增加shiro权限认证,然后也在考虑用my ...