嘟嘟嘟




这题只要往正确的方面想,就很简单。




首先,这是一道图论题

想到这,这题就简单了。对于两个数\(i\)和\(j\),如果\(i\)比\(j\)大,就从\(i\)向\(j\)连边。然后如果图中存在环的话就无解,否则DAG上dp就完事啦。

但是如果暴力连边,最高就能达到\(O(k ^ 3)\)复杂度。然后考虑到是向连续区间连边,就可以线段树优化建图了。

我刚开始就这么写的,过是过了,但后来看题解才发现我这最坏也能达到\(O(n ^ 2logn)\)复杂度,实际上应该把这\(k\)个点向一个虚拟结点连边权为1的边,然后虚拟点向区间连边权为0的边,就能避免两两匹配\(O(n ^ 2)\)了。




就放一个我刚开始写的不太完美的代码吧,题解说的懒得写了。




19.7.8update,关于找环,直接拓扑排序,最后看还有没有入度为0的点就行了。(看以前的代码,还多写了个tarjan缩点,判联通块点数是否大于1……麻烦了)

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 1e9;
const db eps = 1e-8;
const int maxn = 2e5 + 5;
const int maxN = 4e6 + 5;
const int maxe = 5e6 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
} int n, m, s, val[maxn], pos[maxn], du[maxN];
struct Edge
{
int nxt, to, w;
}e[maxe];
int head[maxN], ecnt = -1;
In void addEdge(int x, int y, int w)
{
++du[y];
e[++ecnt] = (Edge){head[x], y, w};
head[x] = ecnt;
} int l[maxn << 2], r[maxn << 2], tIn[maxn << 2], tcnt = 0;
In void build(int L, int R, int now)
{
l[now] = L; r[now] = R;
if(L == R) {tIn[now] = L; return;}
tIn[now] = ++tcnt;
int mid = (L + R) >> 1;
build(L, mid, now << 1);
build(mid + 1, R, now << 1 | 1);
addEdge(tIn[now], tIn[now << 1], 0);
addEdge(tIn[now], tIn[now << 1 | 1], 0);
}
In void update(int L, int R, int now, int x, int w)
{
if(L > R) return;
if(l[now] == L && r[now] == R)
{
addEdge(x, tIn[now], w);
return;
}
int mid = (l[now] + r[now]) >> 1;
if(R <= mid) update(L, R, now << 1, x, w);
else if(L > mid) update(L, R, now << 1 | 1, x, w);
else update(L, mid, now << 1, x, w), update(mid + 1, R, now << 1 | 1, x, w);
} int dp[maxN];
In bool topo()
{
fill(dp + 1, dp + tcnt + 1, INF);
queue<int> q;
for(int i = 1; i <= tcnt; ++i) if(!du[i]) q.push(i);
while(!q.empty())
{
int now = q.front(); q.pop();
if(val[now])
{
if(dp[now] < val[now]) return 0;
dp[now] = val[now];
}
for(int i = head[now], v; ~i; i = e[i].nxt)
{
v = e[i].to;
dp[v] = min(dp[v], dp[now] - e[i].w);
if(!--du[v]) q.push(v);
}
}
for(int i = 1; i <= tcnt; ++i) if(du[i]) return 0;
return 1;
} int main()
{
// freopen("ha.in", "r", stdin);
// freopen("ha.out", "w", stdout);
Mem(head, -1);
n = read(), s = read(), m = read();
for(int i = 1, x; i <= s; ++i) x = read(), val[x] = read();
tcnt = n; build(1, n, 1);
for(int i = 1; i <= m; ++i)
{
int L = read(), R = read(), K = read();
pos[0] = L - 1;
for(int j = 1; j <= K; ++j) pos[j] = read();
for(int j = 1; j <= K; ++j)
{
for(int k = 1; k <= K; ++k)
update(pos[k - 1] + 1, pos[k] - 1, 1, pos[j], 1);
update(pos[K] + 1, R, 1, pos[j], 1);
}
}
if(!topo()) {puts("NIE"); return 0;}
puts("TAK");
for(int i = 1; i <= n; ++i) write(val[i] ? val[i] : dp[i]), space; enter;
return 0;
}

[POI2015]PUS的更多相关文章

  1. P3588 [POI2015]PUS(拓扑排序+线段树)

    P3588 [POI2015]PUS 对于每个$(l,r,k)$,将$k$个位置向剩下$r-l-k+1$个位置连边,边权为$1$,这样就保证$k$个位置比剩下的大 先给所有位置填$1e9$保证最优 然 ...

  2. P3588 【[POI2015]PUS】(线段树优化建边)

    P3588 [[POI2015]PUS] 终于有个能让我一遍过的题了,写篇题解纪念一下 给定长度为n的序列和其中部分已知的数,还有m个大小关系:区间\([l,r]\)中,有k个给定的数比剩下的\(r- ...

  3. 洛谷P3588 [POI2015]PUS

    题面 sol:说了是线段树优化建图的模板... 就是把一整个区间的点连到一个点上,然后用那个点来连需要连一整个区间的点就可以了,就把边的条数优化成n*log(n)了 #include <queu ...

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

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

  5. luoguP3588_[POI2015]PUS

    题意 有一个\(n\)个数的序列,已知其中的\(k\)个数,然后有\(m\)个信息,每个信息给出区间\([l,r]\),和\(k\)个数,表示区间\([l,r]\)中这\(k\)个数大于剩下的\(r- ...

  6. P3588 [POI2015]PUS

    好题 思路:线段树优化建图+拓扑DP or 差分约束(都差不多): 提交:3次 错因:眼瞎没看题,Inf写的0x3f3f3f3f 题解: 类似差分约束的模型,\(a<b\rightarrow a ...

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

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

  8. POI2015 解题报告

    由于博主没有BZOJ权限号, 是在洛咕做的题~ 完成了13题(虽然有一半难题都是看题解的QAQ)剩下的题咕咕咕~~ Luogu3585 [POI2015]PIE Solution 模拟, 按顺序搜索, ...

  9. Luogu P3783 [SDOI2017]天才黑客

    题目大意 一道码量直逼猪国杀的图论+数据结构题.我猪国杀也就一百来行 首先我们要看懂鬼畜的题意,发现其实就是在一个带权有向图上,每条边有一个字符串信息.让你找一个点出发到其它点的最短路径.听起来很简单 ...

随机推荐

  1. 不可思议的纯 CSS 实现鼠标跟随效果

    直接进入正题,鼠标跟随,顾名思义,就是元素会跟随着鼠标的移动而作出相应的运动.大概类似于这样: 通常而言,CSS 负责表现,JavaScript 负责行为.而鼠标跟随这种效果属于行为,要实现通常都需要 ...

  2. 使用 docker-compose 快速安装Jenkins

    本文分享在 docker 环境中,使用 docker-compose.yml 快速安装 Jenkins,以及使用主机中的 docker 打包推送镜像到阿里云 博客园的第100篇文章达成,2019的第一 ...

  3. 01 JVM 从入门到实战 | 什么是 JVM

    什么是 JVM 先来看下百度百科的解释: JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,JVM 是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算 ...

  4. java SE Development kit 8 Update 201 (64-bit) 的安装相关

    登录http://www.oracle.com,下载JDK(J2SE) JDK 1.0,1.1,1.2,1.3,1.4 1.5 (JDK5.0) à支持注解.支持泛型   1.6(JDK6.0) à ...

  5. Identity Server 4 预备知识 -- OAuth 2.0 简介

    OAuth 2.0 简介 OAuth有一些定义: OAuth 2.0是一个委托协议, 它可以让那些控制资源的人允许某个应用以代表他们来访问他们控制的资源, 注意是代表这些人, 而不是假冒或模仿这些人. ...

  6. [Abp vNext 源码分析] - 3. 依赖注入与拦截器

    一.简要说明 ABP vNext 框架在使用依赖注入服务的时候,是直接使用的微软提供的 Microsoft.Extensions.DependencyInjection 包.这里与原来的 ABP 框架 ...

  7. Puppeteer 截图及相关问题

    Puppeteer 是 Headless Chrome 的 Node.js 封装.通过它可方便地对页面进行截图,或者保存成 PDF. 镜像的设置 因为其使用了 Chromium,其源在 Google ...

  8. DSAPI.网络.网卡信息属性表

    DSAPI.网络.网卡信息属性表 其中,带有ReadOnly的属性只可读不可改,不带ReadOnly的属性即可读也可直接修改,如IP地址,Mac地址等 丢弃接收数据包数: 0 丢弃发送数据包数: 0 ...

  9. JavaScript 中最​​重要的保留字

    JavaScript 保留了一些关键字,这些关键字在当前的语言版本中并没有使用,但在以后 JavaScript 扩展中会用到. abstract else instanceof super boole ...

  10. 获取url特定参数

    获取通过url拼接的特定参数值: // 获取url指定参数 function getUrlParams(name) { var reg = new RegExp("(^|&)&quo ...