A - 奶酪
直接用并查集维护即可。(本来一个dfs就够了)
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <iostream>
#include <queue>
#include <stack>
#define rep(i, a, b) for(rint (i) = (a), __omega = (b); (i) <= __omega; ++(i))
#define rint rg int
#define rg register
namespace work {
int F() {
rg char ch; rint x, a;
while(ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
if(ch == '-') a = -1, ch = getchar(); else a = 1;
x = ch-'0';
while(ch = getchar(), ch >= '0' && ch <= '9')
x = (x<<1)+(x<<3)+ch-'0';
return x*a;
}
struct point {
int x, y, z;
point(int X = 0, int Y = 0, int Z = 0) : x(X), y(Y), z(Z) { }
long long dis2() { return 1ll*x*x+1ll*y*y+1ll*z*z; }
point operator-(rg const point &that) { return point(x-that.x, y-that.y, z-that.z); }
} p[1010];
int fa[1010], siz[1010];
int find(rint x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
void unit(rint x, rint y) {
x = find(x), y = find(y);
if(siz[x] < siz[y]) std::swap(x, y);
siz[x] += siz[y]; fa[y] = x;
}
void solve() {
rint n, h;
n = F(), h = F();
rg long long r;
r = F();
rep(i, 1, n)
fa[i] = i, siz[i] = 1, p[i].x = F(), p[i].y = F(), p[i].z = F();
fa[n+1] = n+1, fa[n+2] = n+2;
siz[n+1] = siz[n+2] = 1;
rep(i, 1, n)
if(p[i].z <= r && p[i].z >= -r)
unit(n+1, i);
rep(i, 1, n)
if(p[i].z >= h-r && p[i].z <= h+r)
unit(n+2, i);
r = r*r<<2;
rep(i, 1, n)
rep(j, i+1, n)
if((p[j]-p[i]).dis2() <= r)
unit(i, j);
if(find(n+1) == find(n+2)) puts("Yes");
else puts("No");
}
void main() {
rint test = F();
while(test--) solve();
}
}
int main() {
//freopen("cheese.in", "r", stdin);
//freopen("cheese.out", "w", stdout);
work::main();
return 0;
}
B - 宝藏
f[i][k][S]表示第i个点深度为k,集合为S的最小值,枚举子集转移即可。
//waz
#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)((x).size()))
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef long long int64;
typedef unsigned int uint;
typedef unsigned long long uint64;
#define gi(x) ((x) = F())
#define gii(x, y) (gi(x), gi(y))
#define giii(x, y, z) (gii(x, y), gi(z))
int F()
{
char ch;
int x, a;
while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
if (ch == '-') ch = getchar(), a = -1;
else a = 1;
x = ch - '0';
while (ch = getchar(), ch >= '0' && ch <= '9')
x = (x << 1) + (x << 3) + ch - '0';
return a * x;
}
int n, m;
int f[14][14][1 << 12];
int t[14][14];
int main()
{
gii(n, m);
memset(t, -1, sizeof t);
for (register int i = 1; i <= m; ++i)
{
register int a, b, c;
giii(a, b, c);
if (t[a][b] == -1)
t[a][b] = t[b][a] = c;
else
t[a][b] = t[b][a] = min(t[a][b], c);
}
memset(f, 63, sizeof f);
register int inf = f[0][0][0];
for (register int k = n - 1; ~k; --k)
{
for (register int i = 1; i <= n; ++i)
f[k][i][(1 << (i - 1))] = 0;
for (register int s = 1; s < (1 << n); ++s)
{
for (register int i = 1; i <= n; ++i)
{
if (!(s & (1 << (i - 1)))) continue;
for (register int ss = s - 1; ss; ss = (ss - 1) & s)
{
if (f[k][i][s ^ ss] == inf) continue;
for (register int j = 1; j <= n; ++j)
{
if (!(ss & (1 << (j - 1)))) continue;
if (t[i][j] == -1) continue;
f[k][i][s] = min(f[k][i][s], f[k + 1][j][ss] + f[k][i][s ^ ss] + (k + 1) * t[i][j]);
}
}
}
}
}
int ans = 1e9;
for (register int i = 1; i <= n; ++i)
ans = min(ans, f[0][i][(1 << n) - 1]);
printf("%d\n", ans);
return 0;
}
C - 列队
用动态开点线段树维护哪些要被删除,再用平衡树维护新添加的即可。
//waz
#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)((x).size()))
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef long long int64;
typedef unsigned int uint;
typedef unsigned long long uint64;
#define gi(x) ((x) = F())
#define gii(x, y) (gi(x), gi(y))
#define giii(x, y, z) (gii(x, y), gi(z))
int F()
{
char ch;
int x, a;
while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
if (ch == '-') ch = getchar(), a = -1;
else a = 1;
x = ch - '0';
while (ch = getchar(), ch >= '0' && ch <= '9')
x = (x << 1) + (x << 3) + ch - '0';
return a * x;
}
const int N = 3e5 + 10;
struct node1
{
int siz;
node1 *ls, *rs;
} tr1[N * 20], *nt1 = tr1, *rt1[N], *nul1;
void ins1(node1 *&o, int l, int r, int x)
{
if (r < x || x < l) return;
if (!o) o = ++nt1;
++(o -> siz);
if (l == r) return;
int mid = (l + r) >> 1;
ins1(o -> ls, l, mid, x);
ins1(o -> rs, mid + 1, r, x);
}
int kth1(node1 *&o, int l, int r, int k)
{
if (l == r) return l;
int ls = 0, rs = 0;
if (o) ls = o -> ls ? o -> ls -> siz : 0, rs = o -> rs ? o -> rs -> siz : 0;
int mid = (l + r) >> 1;
ls = (mid - l + 1) - ls;
rs = (r - mid) - rs;
if (k <= ls) return kth1(o ? o -> ls : nul1, l, mid, k);
else return kth1(o ? o -> rs : nul1, mid + 1, r, k - ls);
}
struct node2
{
int64 val;
int rnd;
int siz;
node2 *son[2];
node2(int64 v = 0) { val = v, rnd = rand(); siz = 1; son[0] = son[1] = 0; }
void push_up()
{
siz = 1;
if (son[0]) siz += son[0] -> siz;
if (son[1]) siz += son[1] -> siz;
}
} tr2[N << 2], *rt2[N], *nt2 = tr2;
int siz2(node2 *x) { return x ? x -> siz : 0; }
node2 *merge(node2 *x, node2 *y)
{
if (!x) return y; if (!y) return x;
if ((x -> rnd) < (y -> rnd))
{
x -> son[1] = merge(x -> son[1], y);
x -> push_up();
return x;
}
else
{
y -> son[0] = merge(x, y -> son[0]);
y -> push_up();
return y;
}
}
pair<node2*, node2*> split(node2 *x, int k)
{
if (!x) return pair<node2*, node2*>(0, 0);
pair<node2*, node2*> ret;
if (k <= siz2(x -> son[0]))
{
ret = split(x -> son[0], k);
x -> son[0] = ret.se;
x -> push_up();
ret.se = x;
return ret;
}
else
{
ret = split(x -> son[1], k - siz2(x -> son[0]) - 1);
x -> son[1] = ret.fi;
x -> push_up();
ret.fi = x;
return ret;
}
}
void ins2(node2 *&x, int64 v)
{
node2 *t = ++nt2;
*t = node2(v);
x = merge(x, t);
}
int64 del2(node2 *&x, int k)
{
pair<node2*, node2*> A = split(x, k - 1);
pair<node2*, node2*> B = split(A.se, 1);
x = merge(A.fi, B.se);
return (B.fi) -> val;
}
int siz[N];
int main()
{
srand(time(0));
int n, m, q;
giii(n, m, q);
for (int i = 1; i <= n; ++i)
ins2(rt2[0], 1LL * i * m), siz[i] = m - 1;
int id = 0;
while (q--)
{
++id;
int x, y;
gii(x, y);
if (y != m)
{
if (y <= siz[x])
{
int v = kth1(rt1[x], 1, m - 1, y);
int64 val = (x - 1LL) * m + v;
printf("%lld\n", val);
ins1(rt1[x], 1, m - 1, v);
int64 cur = del2(rt2[0], x);
ins2(rt2[x], cur);
ins2(rt2[0], val);
--siz[x];
}
else
{
int64 val = del2(rt2[x], y - siz[x]);
printf("%lld\n", val);
int64 cur = del2(rt2[0], x);
ins2(rt2[x], cur);
ins2(rt2[0], val);
}
}
else
{
int64 val = del2(rt2[0], x);
ins2(rt2[0], val);
printf("%lld\n", val);
}
}
return 0;
}