-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
774 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
#include <algorithm> | ||
#include <cstdio> | ||
int read() { | ||
int res = 0, c; | ||
do | ||
c = getchar(); | ||
while(c < '0' || c > '9'); | ||
while('0' <= c && c <= '9') { | ||
res = res * 10 + c - '0'; | ||
c = getchar(); | ||
} | ||
return res; | ||
} | ||
void write(int x) { | ||
if(x >= 10) | ||
write(x / 10); | ||
putchar('0' + x % 10); | ||
} | ||
const int size = 1000005, maxv = size * 4, | ||
maxe = size * 2; | ||
struct Edge { | ||
int to, nxt; | ||
} E[maxe]; | ||
int last[size * 2], cnt = 0; | ||
void addEdgeImpl(int u, int v) { | ||
++cnt; | ||
E[cnt].to = v, E[cnt].nxt = last[u]; | ||
last[u] = cnt; | ||
} | ||
void addEdge(int u, int a, int v, int b) { | ||
u = u << 1 | a, v = v << 1 | b; | ||
addEdgeImpl(u, v); | ||
addEdgeImpl(v ^ 1, u ^ 1); | ||
} | ||
int pre[size], nxt[size], n; | ||
void genNxt(int u, int* ed, int& lcnt) { | ||
int col = u & 1, id = u >> 1; | ||
if(id <= n) { | ||
if(col) { | ||
if(pre[id]) | ||
ed[lcnt++] = (pre[id] + n) << 1; | ||
ed[lcnt++] = (id + n) << 1 | 1; | ||
} | ||
} else { | ||
int rid = id - n; | ||
if(col) { | ||
if(nxt[rid]) { | ||
ed[lcnt++] = nxt[rid] << 1; | ||
ed[lcnt++] = (nxt[rid] + n) << 1 | 1; | ||
} | ||
} else { | ||
ed[lcnt++] = rid << 1; | ||
if(pre[rid]) | ||
ed[lcnt++] = (pre[rid] + n) << 1; | ||
} | ||
} | ||
} | ||
int dfn[maxv], low[maxv], icnt = 0, st[maxv], top = 0, | ||
col[maxv], ccnt = 0; | ||
bool flag[maxv]; | ||
void DFS(int u); | ||
void update(int u, int v) { | ||
if(dfn[v]) { | ||
if(flag[v]) | ||
low[u] = std::min(low[u], dfn[v]); | ||
} else { | ||
DFS(v); | ||
low[u] = std::min(low[u], low[v]); | ||
} | ||
} | ||
void DFS(int u) { | ||
dfn[u] = low[u] = ++icnt; | ||
flag[u] = true; | ||
st[++top] = u; | ||
if((u >> 1) <= n) { | ||
for(int i = last[u]; i; i = E[i].nxt) { | ||
int v = E[i].to; | ||
update(u, v); | ||
} | ||
} | ||
int ed[2], lcnt = 0; | ||
genNxt(u, ed, lcnt); | ||
for(int i = 0; i < lcnt; ++i) | ||
update(u, ed[i]); | ||
if(dfn[u] == low[u]) { | ||
++ccnt; | ||
int v; | ||
do { | ||
v = st[top--]; | ||
flag[v] = false; | ||
col[v] = ccnt; | ||
} while(v != u); | ||
} | ||
} | ||
int gid[size], ans[size]; | ||
int main() { | ||
n = read(); | ||
int m = read(); | ||
int k = read(); | ||
for(int i = 1; i <= m; ++i) { | ||
int u = read(); | ||
int v = read(); | ||
addEdge(u, 0, v, 1); | ||
} | ||
for(int i = 1; i <= k; ++i) { | ||
int w = read(), last = 0; | ||
for(int j = 0; j < w; ++j) { | ||
int u = read(); | ||
gid[u] = i; | ||
ans[i] = u; | ||
pre[u] = last; | ||
nxt[last] = u; | ||
last = u; | ||
} | ||
} | ||
int end = n << 2 | 1; | ||
for(int i = 2; i <= end; ++i) { | ||
if(!dfn[i]) | ||
DFS(i); | ||
if((i & 1) && col[i] == col[i ^ 1]) { | ||
puts("NIE"); | ||
return 0; | ||
} | ||
} | ||
puts("TAK"); | ||
for(int i = 1; i <= n; ++i) | ||
if(col[i << 1 | 1] < col[i << 1]) | ||
ans[gid[i]] = i; | ||
for(int i = 1; i <= k; ++i) { | ||
write(ans[i]); | ||
putchar(' '); | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
#include <algorithm> | ||
#include <cstdio> | ||
#include <set> | ||
namespace IO { | ||
char in[1 << 22]; | ||
void init() { | ||
fread(in, 1, sizeof(in), stdin); | ||
} | ||
char getc() { | ||
static char* S = in; | ||
return *S++; | ||
} | ||
} | ||
typedef long long Int64; | ||
int read() { | ||
int res = 0, c; | ||
bool flag = false; | ||
do { | ||
c = IO::getc(); | ||
flag |= c == '-'; | ||
} while(c < '0' || c > '9'); | ||
while('0' <= c && c <= '9') { | ||
res = res * 10 + c - '0'; | ||
c = IO::getc(); | ||
} | ||
return flag ? -res : res; | ||
} | ||
const int size = 100005; | ||
struct Pos { | ||
int id, x, y; | ||
} P[size]; | ||
Int64 dist(const Pos& a, const Pos& b) { | ||
Int64 dx = a.x - b.x, dy = a.y - b.y; | ||
return dx * dx + dy * dy; | ||
} | ||
bool cmpX(const Pos& a, const Pos& b) { | ||
return a.x < b.x; | ||
} | ||
bool cmpY(const Pos& a, const Pos& b) { | ||
return a.y < b.y; | ||
} | ||
struct Node { | ||
int l, r, minx, maxx, miny, maxy; | ||
void update(const Node& rhs) { | ||
minx = std::min(minx, rhs.minx); | ||
maxx = std::max(maxx, rhs.maxx); | ||
miny = std::min(miny, rhs.miny); | ||
maxy = std::max(maxy, rhs.maxy); | ||
} | ||
Int64 evalMax(const Pos& a) const { | ||
Int64 dx1 = minx - a.x, dx2 = maxx - a.x; | ||
Int64 dy1 = miny - a.y, dy2 = maxy - a.y; | ||
return std::max(dx1 * dx1, dx2 * dx2) + | ||
std::max(dy1 * dy1, dy2 * dy2); | ||
} | ||
} T[size]; | ||
#define ls T[u].l | ||
#define rs T[u].r | ||
int build(int l, int r, bool axis) { | ||
if(l > r) | ||
return 0; | ||
int m = (l + r) >> 1; | ||
std::nth_element(P + l, P + m, P + r + 1, | ||
axis ? cmpX : cmpY); | ||
T[m].minx = T[m].maxx = P[m].x; | ||
T[m].miny = T[m].maxy = P[m].y; | ||
axis ^= 1; | ||
T[m].l = build(l, m - 1, axis); | ||
T[m].r = build(m + 1, r, axis); | ||
if(T[m].l) | ||
T[m].update(T[T[m].l]); | ||
if(T[m].r) | ||
T[m].update(T[T[m].r]); | ||
return m; | ||
} | ||
struct Info { | ||
Int64 d; | ||
int u; | ||
Info(Int64 d, int u) : d(d), u(u) {} | ||
bool operator<(const Info& rhs) const { | ||
if(d != rhs.d) | ||
return d < rhs.d; | ||
return u > rhs.u; | ||
} | ||
}; | ||
typedef std::set<Info> Heap; | ||
Heap cur; | ||
void query(const Pos& p, int u) { | ||
if(u == 0) | ||
return; | ||
{ | ||
Info md(dist(p, P[u]), P[u].id); | ||
if(*cur.begin() < md) { | ||
cur.erase(cur.begin()); | ||
cur.insert(md); | ||
} | ||
} | ||
Int64 lv = T[ls].evalMax(p), rv = T[rs].evalMax(p); | ||
if(lv > rv) { | ||
if(lv >= cur.begin()->d) | ||
query(p, ls); | ||
if(rv >= cur.begin()->d) | ||
query(p, rs); | ||
} else { | ||
if(rv >= cur.begin()->d) | ||
query(p, rs); | ||
if(lv >= cur.begin()->d) | ||
query(p, ls); | ||
} | ||
} | ||
int main() { | ||
IO::init(); | ||
int n = read(); | ||
for(int i = 1; i <= n; ++i) { | ||
P[i].id = i; | ||
P[i].x = read(); | ||
P[i].y = read(); | ||
} | ||
int rt = build(1, n, false); | ||
int m = read(); | ||
for(int i = 0; i < m; ++i) { | ||
Pos p; | ||
p.x = read(); | ||
p.y = read(); | ||
int k = read(); | ||
cur.clear(); | ||
for(int j = 0; j < k; ++j) | ||
cur.insert(Info(-1, -j)); | ||
query(p, rt); | ||
printf("%d\n", cur.begin()->u); | ||
} | ||
return 0; | ||
} |
Oops, something went wrong.