题目:
题目(别找我要权限号,我没有)
这一题裸的线段树优化建图,直接码就是了。我尝试一下不看其他人的代码,直接打代码,结果险些没有过,加了快读,并且时限20s,空间512MB才过(处理器i3-6100)(bzoj的题目上面写的就是这个标准)。
果然我还是太弱了。
Code:
//线段树优化建图
//函数名不要在意
//函数返回的void不要在意
//Chtolly
#include <bits/stdc++.h>
#ifdef wll
#include <windows.h>
#endif
#define xx first
#define yy second
#define ll long long
#define _for(i,a,b) for(int i=(a);i<=(b);++i)
#define abs(n) ((n) > 0 ? (n) : -(n))
using namespace std;
struct _in {
const _in &operator, (int &a) const {
a = 0;
char k = getchar ();
int f = 1;
while (k > '9' || k < '0') {
if (k == '-') {
f = -1;
}
k = getchar ();
}
while (k >= '0' && k <= '9') {
a = a * 10 + k - '0';
k = getchar ();
}
a *= f;
return *this;
}
}in;
const int N = 1000000 + 5, M = N * 10;
int l[M], r[M], ch[M][2], tot;
int fr[M << 1], to[M << 1], h[M], tot2;
bool w[M];
inline void add (int u, int v, bool l) {
tot2++;
fr[tot2] = h[u];
to[tot2] = v;
h[u] = tot2;
w[tot2] = l;
return (void)("神奇");
}
int n, m, P, root1, root2;
int storer[M], Pos[M];
void build (int u, int v, bool con) {
int p = ++tot;
l[p] = u;
r[p] = v;
if (u == v) {
if (con) {
storer[u] = p;
}
else {
add (storer[u], p, 0);
Pos[u] = p;
}
return (void)("毒瘤");
}
int mid = (u + v) / 2;
if (con) {
add (p, tot + 1, 0);
}
else {
add (tot + 1, p, 0);
}
ch[p][0] = tot + 1;
build (u, mid, con);
if (con) {
add (p, tot + 1, 0);
}
else {
add (tot + 1, p, 0);
}
ch[p][1] = tot + 1;
build (mid + 1, v, con);
return (void)("真的毒瘤");
}
void solve (int u, int v, int p, int aim, bool con) {
if (u <= l[p] && v >= r[p]) {
if (con) {
add (aim, p, 0);
}
else {
add (p, aim, 0);
}
return ;
}
int mid = (l[p] + r[p]) / 2;
if (u <= mid) {
solve (u, v, ch[p][0], aim, con);
}
if (v > mid) {
solve (u, v, ch[p][1], aim, con);
}
return (void)("OI大法好");
}
inline void ak (int u, int v, int m, int n) {
tot += 2;
solve (u, v, root2, tot - 1, 0);
add (tot - 1, tot, 1);
solve (m, n, root1, tot, 1);
return (void)("退役了");
}
int dis[M];
bool inq[M];
inline void AK() {
int f = Pos[P];
memset (dis, 0x7F, sizeof (dis));
dis[f] = 0;
priority_queue <pair<int, int> > Q;
Q.push (make_pair (0, f));
inq[f] = 1;
while (Q.size()) {
int u = Q.top().second;
Q.pop ();
inq[u] = 0;
for (int i = h[u]; i; i = fr[i]) {
if (dis[to[i]] > dis[u] + w[i]) {
dis[to[i]] = dis[u] + w[i];
if (!inq[to[i]]) {
inq[to[i]] = 1;
Q.push(make_pair (-dis[to[i]], to[i]));
}
}
}
}
for (int i = 1; i <= n; ++i) {
printf ("%d\n", dis[Pos[i]]);
}
return (void)("快A");
}
int main () {
// #ifdef wll
freopen ("testdata.in", "r", stdin);
freopen ("testdata.out", "w", stdout);
// #endif
scanf ("%d%d%d", &n, &m, &P);
root1 = tot + 1;
build (1, n, 1);
root2 = tot + 1;
build (1, n, 0);
for (int i = 1; i <= m; ++i) {
int a, b, c, d;
in, a, b, c, d;
ak (a, b, c, d);
ak (c, d, a, b);
}
AK();
return 0 + 0 - 0;
}