bzoj 4383: [POI2015]Pustynia
Posted AωD!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 4383: [POI2015]Pustynia相关的知识,希望对你有一定的参考价值。
复习了一下线段树优化建图的姿势,在线段树上连边跑拓扑排序
这题竟然卡vector……丧病
#include <bits/stdc++.h> #define N 1810000 using namespace std; int s, n, m; int pi[N], vis[N]; int lt[N], nt[N], bi[N], ci[N]; int lp[N], np[N], bp[N]; int tl; int lb[N], rb[N], lc[N], rc[N]; int out[N], intr[N]; int Q[N], fr, bc; inline void build(int a, int b, int c) { nt[++ tl] = lt[a]; lt[a] = tl; bi[tl] = b; ci[tl] = c; np[tl] = lp[b]; lp[b] = tl; bp[tl] = a; out[a] ++; /* bi[a].push_back(b); bp[b].push_back(a); ci[a].push_back(c); */ //printf("%d %d %d\n", a, b, c); } int tot; void dfs_build(int t, int l, int r, int x) { if (l > r) return; if (l <= lb[t] && rb[t] <= r) {build(x, t, 0); return;} if (l <= rb[lc[t]]) dfs_build(lc[t], l, r, x); if (r >= lb[rc[t]]) dfs_build(rc[t], l, r, x); } int build_tree(int l, int r) { int t = ++ tot; lb[t] = l; rb[t] = r; if (l != r) { lc[t] = build_tree(l, (l + r) / 2); rc[t] = build_tree((l + r) / 2 + 1, r); build(t, lc[t], 0); build(t, rc[t], 0); } else intr[l] = t; return t; } inline int read() { int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } int main() { n = read(); s = read(); m = read(); build_tree(1, n); for (int i = 1; i <= s; ++ i) { int p, d; p = read(); d = read(); pi[intr[p]] = d; } //return 0; for (int i = 1; i <= m; ++ i) { int l, r, k; l = read(); r = read(); k = read(); for (int j = 1, p = l - 1; j <= k + 1; ++ j) { int a; if (j <= k) { a = read(); build(intr[a], tot + i, 1); } else a = r + 1; if ((a - 1) - (p + 1) <= 10) { for (int q = p + 1; q < a; ++ q) build(tot + i, intr[q], 0); } else dfs_build(1, p + 1, a - 1, tot + i); p = a; } } for (int i = 1; i <= m + tot; ++ i) if (!out[i]) Q[bc ++] = i; while (fr != bc) { int hd = Q[fr ++]; vis[hd] = 1; int mx = 1; for (int i = lt[hd]; i; i = nt[i]) mx = max(mx, pi[bi[i]] + ci[i]); if (!pi[hd]) { if (mx > 1000000000) { puts("NIE"); return 0; } pi[hd] = mx; } else if (mx > pi[hd]) { puts("NIE"); return 0; } for (int i = lp[hd]; i; i = np[i]) { out[bp[i]] --; if (!out[bp[i]]) Q[bc ++] = bp[i]; } } for (int i = 1; i <= m + tot; ++ i) if (!vis[i]) {puts("NIE"); return 0;} puts("TAK"); for (int i = 1; i <= n; ++ i) printf("%d ", pi[intr[i]]); }
话说是不是在主席树上也可以干一样的事情呢(手动斜眼
以上是关于bzoj 4383: [POI2015]Pustynia的主要内容,如果未能解决你的问题,请参考以下文章