NEERC天天被搬还是做了好了。
Abbreviation
模拟。
#define FIO "abbreviation"
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
const int MAXN = 500005;
int n, p[MAXN];
string t[MAXN];
char s[MAXN];
inline bool In(int x, int l, int r)
{
return x >= l && x <= r;
}
inline int Find(int x)
{
if (!In(s[x], 'A', 'Z') || !In(s[x + 1], 'a', 'z'))
return 0;
for (x ++; In(s[x], 'a', 'z'); x ++);
if (In(s[x], 'A', 'Z'))
return 0;
return x;
}
inline int Chk(int x)
{
int y, z;
if (!(y = Find(x)) || s[y] != ' ' || !(z = Find(y + 1)))
return 0;
t[x] += s[x], t[x] += s[y + 1];
while (true)
{
if (s[z] != ' ' || !(y = Find(z + 1)))
return z - 1;
t[x] += s[z + 1];
z = y;
}
}
int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#else
freopen(FIO".in", "r", stdin);
freopen(FIO".out", "w", stdout);
#endif
for (char c = getchar(); ~c; c = getchar())
s[++ n] = c;
for (int i = 1, j; i <= n; i ++)
if (!In(s[i - 1], 'A', 'Z') && !In(s[i - 1], 'a', 'z'))
if (j = Chk(i))
p[i] = 1, p[j] = 2, i = j;
for (int i = 1; i <= n; i ++)
{
if (p[i] == 1)
printf("%s (", t[i].c_str());
putchar(s[i]);
if (p[i] == 2)
putchar(')');
}
}
Binary Code
暴力是枚举两个点的两种状态,看是否一个是另一个的前缀,跑2-SAT。
考虑用trie树优化建边,分别是前缀和和后缀和(表示选没选)。
#define FIO "binary"
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
const int MAXN = 1000005;
const int MAXM = 4000005;
int n, tot, len, cnt, num, scc[MAXM], par[MAXN], pos[MAXN], st[MAXN], ed[MAXN], tst[MAXN], ted[MAXN], dfn[MAXM], nxt[MAXN][2];
vector <int> adj[MAXM], vec[MAXN], G[MAXM];
char s[MAXN], ch[MAXN];
bool res[MAXN];
inline void Add(int p)
{
int cur = 0;
for (int i = 1; i <= len; cur = nxt[cur][s[i ++] - '0'])
if (!nxt[cur][s[i] - '0'])
par[nxt[cur][s[i] - '0'] = ++ cnt] = cur;
pos[p] = cur;
vec[cur].pb(p);
}
inline void Build()
{
for (int i = 1; i <= cnt; i ++)
if (!vec[i].empty())
{
for (int j = 0; j < vec[i].size(); j ++)
if (!j)
adj[++ tot].pb(vec[i][j] ^ 1);
else
adj[vec[i][j]].pb(tot), adj[tot + 1].pb(tot), adj[++ tot].pb(vec[i][j] ^ 1);
tst[i] = tot;
for (int j = 0; j < vec[i].size(); j ++)
if (!j)
adj[vec[i][j]].pb(++ tot);
else
adj[tot].pb(vec[i][j] ^ 1), adj[tot].pb(tot + 1), adj[vec[i][j]].pb(++ tot);
ted[i] = tot;
}
for (int i = 2; i <= (n << 1 | 1); i ++)
for (int j = par[pos[i]]; j; j = par[j])
if (!vec[j].empty())
adj[i].pb(tst[j]), adj[ted[j]].pb(i ^ 1);
}
int sta[MAXM], low[MAXM], tim, tp;
inline void Dfs(int x)
{
dfn[x] = low[x] = ++ tim;
sta[++ tp] = x;
for (auto y : adj[x])
if (!dfn[y])
Dfs(y), low[x] = min(low[x], low[y]);
else if (!scc[y])
low[x] = min(low[x], dfn[y]);
if (dfn[x] == low[x])
{
int cur = 0; num ++;
while (cur ^ x)
scc[cur = sta[tp --]] = num;
}
}
int vis[MAXM], opp[MAXM], deg[MAXM], q[MAXM], ql, qr;
inline void Print()
{
for (int i = 1; i <= n; i ++)
opp[scc[i << 1]] = scc[i << 1 | 1], opp[scc[i << 1 | 1]] = scc[i << 1];
for (int x = 2; x <= tot; x ++)
for (auto y : adj[x])
if (scc[x] ^ scc[y])
G[scc[y]].pb(scc[x]), deg[scc[x]] ++;
for (int i = 1; i <= num; i ++)
if (!deg[i])
q[++ qr] = i;
while (ql ^ qr)
{
int x = q[++ ql];
if (!vis[x])
vis[x] = 1, vis[opp[x]] = -1;
for (auto y : G[x])
if (!-- deg[y])
q[++ qr] = y;
}
for (int i = 2; i <= (n << 1 | 1); i ++)
if (~vis[scc[i]])
res[i >> 1] = i & 1;
}
int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#else
freopen(FIO".in", "r", stdin);
freopen(FIO".out", "w", stdout);
#endif
n = Read(), tot = n << 1 | 1;
for (int i = 1, t = 1; i <= n; i ++)
{
scanf("%s", s + 1), len = strlen(s + 1);
st[i] = t;
for (int j = 1; j <= len; j ++)
ch[t ++] = s[j];
ed[i] = t;
for (int j = 1; j <= len; j ++)
if (s[j] == '?')
{
s[j] = '0', Add(i << 1);
s[j] = '1', Add(i << 1 | 1);
break;
}
else if (j == len)
Add(i << 1), Add(i << 1 | 1);
}
Build();
for (int i = 2; i <= tot; i ++)
if (!dfn[i])
Dfs(i);
for (int i = 1; i <= n; i ++)
if (scc[i << 1] == scc[i << 1 | 1])
return puts("NO"), 0;
puts("YES");
Print();
for (int i = 1; i <= n; putchar(10), i ++)
for (int j = st[i]; j < ed[i]; j ++)
if (ch[j] == '?')
putchar(res[i] + '0');
else
putchar(ch[j]);
return 0;
}
Cactus Construction
先把所有环和桥边分开,然后随便构造一下就好了。
详见代码。
#define FIO "cactus"
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
const int MAXN = 50005;
struct Node
{
int opt, a, b, c;
Node(int _opt = 0, int _a = 0, int _b = 0, int _c = 0)
{
opt = _opt, a = _a, b = _b, c = _c;
}
};
int n, m, tim, cnt, par[MAXN], a[MAXN], dfn[MAXN];
vector <int> adj[MAXN], hav[MAXN], cir[MAXN];
vector <Node> ans;
bool f[MAXN];
inline void Dfs(int x)
{
dfn[x] = ++ tim;
for (auto y : adj[x])
if (y ^ par[x])
if (!dfn[y])
par[y] = x, Dfs(y);
else if (dfn[y] < dfn[x])
{
hav[y].pb(++ cnt);
cir[cnt].pb(y);
for (int i = x; i ^ y; i = par[i])
cir[cnt].pb(i);
}
}
inline void Solve(int x)
{
for (auto c : hav[x])
{
for (auto y : cir[c])
if (y ^ x)
f[y] = 1;
for (auto y : cir[c])
if (y ^ x)
Solve(y);
for (int i = 1; i < cir[c].size(); i ++)
{
int p = cir[c][i - 1], q = cir[c][i];
ans.pb(Node(2, p, 1, 3));
ans.pb(Node(1, p, q));
ans.pb(Node(3, p, 1, 3));
ans.pb(Node(2, p, 3, i == 1 ? 4 : 2));
}
int y = cir[c].back();
ans.pb(Node(3, x, 1, 4));
ans.pb(Node(2, x, 1, 2));
ans.pb(Node(2, x, 4, 1));
}
for (auto y : adj[x])
if (!f[y])
{
f[y] = 1, Solve(y);
ans.pb(Node(2, y, 1, 3));
ans.pb(Node(1, x, y));
ans.pb(Node(3, x, 1, 3));
ans.pb(Node(2, x, 3, 2));
}
}
int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#else
freopen(FIO".in", "r", stdin);
freopen(FIO".out", "w", stdout);
#endif
n = Read(), m = Read();
while (m --)
{
int x = Read();
for (int i = 1; i <= x; i ++)
a[i] = Read();
for (int i = 1; i < x; i ++)
adj[a[i]].pb(a[i + 1]), adj[a[i + 1]].pb(a[i]);
}
Dfs(1);
f[1] = 1;
Solve(1);
printf("%d\n", ans.size());
for (auto e : ans)
if (e.opt == 1)
printf("j %d %d\n", e.a, e.b);
else if (e.opt == 2)
printf("r %d %d %d\n", e.a, e.b, e.c);
else if (e.opt == 3)
printf("c %d %d %d\n", e.a, e.b, e.c);
}
Delight for a Cat
考虑费用流,一个点如果选择睡觉那就会影响之后的k个东西,直接跳
#define FIO "delight"
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
const int MAXN = 1005;
const int MAXM = 6005;
const int INF = 0x3f3f3f3f;
namespace Flow
{
struct edge
{
int p, v, w, c;
} e[MAXM];
int V, S, T, hed[MAXN], e_cnt = 1;
LL ans, dis[MAXN];
bool vis[MAXN];
inline void Init(int n)
{
V = n, e_cnt = 1;
for (int i = 0; i < V; i ++)
hed[i] = 0;
}
inline void Add(int x, int y, int w, int c) { e[++ e_cnt] = {y, hed[x], w, c}; hed[x] = e_cnt; }
inline void Addedge(int x, int y, int w, int c) { Add(x, y, w, c); Add(y, x, 0, -c); }
inline bool Spfa()
{
for (int i = 0; i < V; i ++)
dis[i] = 1LL << 60, vis[i] = 0;
queue <int> q;
dis[S] = 0; q.push(S);
while (!q.empty())
{
int x = q.front(); q.pop(); vis[x] = 0;
for (int i = hed[x]; i; i = e[i].v)
if (e[i].w && dis[e[i].p] > dis[x] + e[i].c)
{
dis[e[i].p] = dis[x] + e[i].c;
if (!vis[e[i].p])
vis[e[i].p] = 1, q.push(e[i].p);
}
}
return dis[T] < 1LL << 60;
}
inline int Dfs(int x, int f)
{
vis[x] = 1;
if (x == T)
return f;
int ret = 0, d;
for (int i = hed[x]; i; i = e[i].v)
if (e[i].w && dis[e[i].p] == dis[x] + e[i].c && !vis[e[i].p])
{
d = Dfs(e[i].p, min(f - ret, e[i].w));
e[i].w -= d; e[i ^ 1].w += d; ret += d;
if (ret == f)
return ret;
}
return ret;
}
inline int Solve()
{
int ret = 0;
while (Spfa())
{
vis[T] = 1;
while (vis[T])
{
for (int i = 0; i < V; i ++)
vis[i] = 0;
int d = Dfs(S, INF);
ret += d; ans += d * dis[T];
}
}
return ret;
}
}
int n, k, p, q, a[MAXN];
int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#else
freopen(FIO".in", "r", stdin);
freopen(FIO".out", "w", stdout);
#endif
using namespace Flow;
n = Read(), k = Read(), p = k - Read(), q = Read();
Flow::Init(n + 3), Flow::T = n + 2;
for (int i = 1; i <= n; i ++)
a[i] -= Read(), ans += a[i];
for (int i = 1; i <= n; i ++)
a[i] += Read();
for (int i = 1; i <= n; i ++)
Addedge(i, i + k <= n ? i + k : T, 1, -a[i]);
for (int i = 1; i <= n; i ++)
Addedge(i, i == n ? T : i + 1, p - q, 0);
for (int i = 1; i <= k; i ++)
Addedge(n + 1, i, INF, 0);
Addedge(S, n + 1, p, 0);
Solve();
printf("%lld\n", -ans);
for (int i = 1; i <= n; i ++)
putchar(e[i << 1].w ? 'S' : 'E');
putchar(10);
return 0;
}
Expect to Wait
随便推一推发现是个一次函数的形式,离线之后打上差分标记。
#define FIO "expect"
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
const int MAXN = 100005;
int n, m, t[MAXN], c[MAXN], l[MAXN];
LL p, q, a[MAXN], b[MAXN], ans[MAXN];
pii e[MAXN];
char ch[2];
int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#else
freopen(FIO".in", "r", stdin);
freopen(FIO".out", "w", stdout);
#endif
n = Read(), m = Read();
for (int i = 1, x, y; i <= n; i ++)
{
scanf("%s", ch);
if (ch[0] == '+')
t[i] = Read(), c[i] = Read();
else
t[i] = Read(), c[i] = -Read();
}
for (int i = 1; i <= m; i ++)
e[i].xx = Read(), e[i].yy = i;
sort(e + 1, e + m + 1);
for (int i = 1; i <= m; i ++)
l[i] = e[i].xx;
for (int i = 1, s = 0, d; i <= n; i ++)
{
s += c[i], d = t[i + 1] - t[i];
if (s < 0)
{
int p = lower_bound(l + 1, l + m + 1, -s) - l;
if (i ^ n)
a[0] -= d, b[0] -= 1LL * d * s, a[p] += d, b[p] += 1LL * d * s;
else
for (int j = 1; j < p; j ++)
ans[e[j].yy] = -1;
}
}
for (int i = 0; i <= m; i ++)
{
p += a[i], q += b[i];
if (~ans[e[i].yy])
ans[e[i].yy] = p * e[i].xx + q;
}
for (int i = 1; i <= m; i ++)
if (ans[i] == -1)
puts("INFINITY");
else
printf("%lld\n", ans[i]);
return 0;
}
Foreign Postcards
暴力想法是枚举一对(i,j),然后用个后缀和来优化一下。
#define FIO "foreign"
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
const int MAXN = 1000005;
long double ans;
int n, a[MAXN];
LL p, q, c, d;
char s[MAXN];
int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#else
freopen(FIO".in", "r", stdin);
freopen(FIO".out", "w", stdout);
#endif
scanf("%s", s + 1); n = strlen(s + 1);
for (int i = 1; i <= n; i ++)
a[i] = s[i] == 'W';
for (int i = 1; i <= n; i ++)
c += a[i], d += !a[i], p += c, q += d;
for (int i = 0; i < n; i ++)
{
double r = i ? 1.0 / (1LL * (n - i) * (n - i + 1)) : 1.0 / n;
ans += r * (a[i + 1] ? q : p);
p -= a[i + 1] * (n - i);
q -= (!a[i + 1]) * (n - i);
}
return printf("%.10Lf\n", ans), 0;
}
Game on Graph
考虑记f(i,j)表示当前在i,第
#define FIO "game"
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
const int MAXN = 100005;
vector <int> adj[MAXN], rev[MAXN];
bool a[MAXN][2], b[MAXN][2];
int n, m, ql, qr, d[MAXN];
pii q[MAXN << 1];
inline void Solve(bool f[MAXN][2])
{
ql = qr = 0;
for (int i = 1; i <= n; i ++)
for (int j = 0; j < 2; j ++)
if (f[i][j])
q[++ qr] = mp(i, j);
for (int i = 1; i <= n; i ++)
d[i] = adj[i].size();
while (ql ^ qr)
{
int x = q[++ ql].xx, p = q[ql].yy;
if (p)
{
for (auto y : rev[x])
if (!f[y][0] && !-- d[y])
f[y][0] = 1, q[++ qr] = mp(y, 0);
}
else
for (auto y : rev[x])
if (!f[y][1])
f[y][1] = 1, q[++ qr] = mp(y, 1);
}
}
int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#else
freopen(FIO".in", "r", stdin);
freopen(FIO".out", "w", stdout);
#endif
n = Read(), m = Read();
for (int i = 1, x, y; i <= m; i ++)
x = Read(), y = Read(), adj[x].pb(y), rev[y].pb(x);
for (int i = 1; i <= n; i ++)
if (adj[i].empty())
a[i][0] = a[i][1] = b[i][0] = 1;
Solve(a);
Solve(b);
for (int i = 1; i <= n; i ++)
if (b[i][0])
putchar('L');
else if (!a[i][0])
putchar('D');
else
putchar('W');
putchar(10);
for (int i = 1; i <= n; i ++)
if (b[i][1])
putchar('W');
else if (a[i][1])
putchar('L');
else
putchar('D');
putchar(10);
return 0;
}
Hard Refactoring
模拟。
#define FIO "hard"
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
const int MAXN = 100005;
int a[MAXN], n = 1 << 15;
vector <pii> ans;
char s[MAXN];
int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#else
freopen(FIO".in", "r", stdin);
freopen(FIO".out", "w", stdout);
#endif
while (fgets(s, MAXN, stdin))
{
int l, r;
if (sscanf(s, "x >= %d && x <= %d", &l, &r) ^ 2)
if (sscanf(s, "x >= %d", &l) ^ 1)
sscanf(s, "x <= %d", &r), l = -n;
else
r = n - 1;
if (l > r)
continue;
a[l + n] ++, a[r + n + 1] --;
}
for (int i = 1; i < MAXN; i ++)
a[i] += a[i - 1];
for (int i = 0; i < MAXN; i ++)
if (a[i])
{
int p = i;
while (a[p + 1])
p ++;
ans.pb(mp(i - n, p - n));
i = p;
}
if (ans.empty())
return puts("false"), 0;
if (ans.size() == 1 && ans[0].xx == -n && ans[0].yy == n - 1)
return puts("true"), 0;
for (int i = 0; i < ans.size(); i ++)
{
pii x = ans[i];
if (x.xx == -n)
printf("x <= %d", x.yy);
else if (x.yy == n - 1)
printf("x >= %d", x.xx);
else
printf("x >= %d && x <= %d", x.xx, x.yy);
if (i < ans.size() - 1)
puts(" ||");
}
putchar(10);
return 0;
}
Indiana Jones and the Uniform Cave
挺厉害的交互题。
考虑用
如果一个点走到了不在栈中的点,那么我们先向上跳(
在栈中的也是走两遍就知道深度了。
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
int n, m, L = 0, R = 1, C = 2, adj[25][25];
inline int Next()
{
char s[15];
scanf("%s", s);
if (s[0] == 'l')
return L;
if (s[0] == 'r')
return R;
if (s[0] == 'c')
return C;
exit(0);
}
inline int Print(int p, int t, int v)
{
printf("%d %s %d\n", p, t ? "right" : "left", v);
fflush(stdout);
return Next();
}
inline void Dfs(int x, int dep)
{
for (int i = 0; i < m; i ++)
{
int val = Print(1, R, 1), cnt = 0;
if (val == C)
Dfs(++ n, adj[x][i] = dep + 1), val = L;
if (val == L)
{
for (; Print(0, L, 0) == L; );
for (; Print(0, R, 0) == R; cnt ++);
for (; Print(0, L, 0) == L; );
for (int i = 1; i <= cnt; i ++)
Print(0, R, 0);
adj[x][i] = dep - cnt;
}
else
{
for (; Print(0, L, 0) == R; cnt ++);
for (int i = 0; i <= cnt; i ++)
Print(0, R, 0);
for (int i = 1; i <= cnt; i ++)
Print(0, R, 0);
adj[x][i] = dep - cnt;
}
}
if (x ^ 1)
{
int pos = -1, val;
for (int i = 0; i < m; i ++)
if (!~pos || adj[x][i] < adj[x][pos])
pos = i;
val = Print((pos + 1) % m, L, (pos + 1) % m);
for (; val == L; val = Print(0, L, 0));
for (; Print(0, R, 0) == R; );
}
}
int main()
{
m = Read();
Next();
Dfs(++ n, 1);
return 0;
}
Jenga Boom
暴力。
#define FIO "jenga"
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
const int MAXN = 5005;
int n, m, h, w, l[MAXN], r[MAXN], c[MAXN], s[MAXN];
bool f[MAXN][MAXN << 1];
inline bool chk()
{
LL cnt[2] = {0, 0}, sum[2] = {0, 0};
for (int i = h, cur = i & 1; i > 1; i --, cur ^= 1)
{
cnt[cur] += c[i], sum[cur] += s[i];
if ((sum[cur ^ 1] + cnt[cur] * n) <= (cnt[0] + cnt[1]) * (l[i - 1] * 2 - 2))
return 1;
if ((sum[cur ^ 1] + cnt[cur] * n) >= (cnt[0] + cnt[1]) * (r[i - 1] * 2))
return 1;
}
return 0;
}
int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#else
freopen(FIO".in", "r", stdin);
freopen(FIO".out", "w", stdout);
#endif
n = Read(), w = Read(), h = Read(), m = Read();
for (int i = 1; i <= h; i ++)
l[i] = 1, r[i] = n, c[i] = n, s[i] = n * n;
for (int i = 1; i <= m; i ++)
{
int x = Read(), y = Read();
f[x][y] = 1;
s[x] -= y * 2 - 1;
if (-- c[x])
{
while (f[x][l[x]])
l[x] ++;
while (f[x][r[x]])
r[x] --;
}
else if (x == h)
h --;
else
return printf("yes\n%d\n", i), 0;
if (chk())
return printf("yes\n%d\n", i), 0;
}
return puts("no"), 0;
}
Kids Designing Kids
三个图异或为
#define FIO "kids"
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
set <pii> A, B, C;
pii a, b, c;
char ch[1005];
inline void Init(set <pii> &S, pii &s)
{
int n = Read(), m = Read(), f = 0;
for (int i = 1; i <= n; i ++)
{
scanf("%s", ch + 1);
for (int j = 1; j <= m; j ++)
if (ch[j] == '*')
{
if (!f)
f = 1, s = mp(-i, -j);
S.insert(mp(i + s.xx, j + s.yy));
}
}
}
inline bool Chk(set <pii> &A, pii &a, set <pii> &B, pii &b, set <pii> &C, pii &c)
{
set <pii> S;
for (auto x : A)
S.insert(x);
for (auto x : B)
if (S.find(x) != S.end())
S.erase(x);
else
S.insert(x);
if (S.size() != C.size())
return 0;
pii s = *S.begin();
for (auto x : C)
if (S.find(mp(x.xx + s.xx, x.yy + s.yy)) == S.end())
return 0;
c = mp(c.xx + s.xx, c.yy + s.yy);
return 1;
}
int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#else
freopen(FIO".in", "r", stdin);
freopen(FIO".out", "w", stdout);
#endif
Init(A, a); Init(B, b); Init(C, c);
if (Chk(A, a, B, b, C, c) || Chk(A, a, C, c, B, b) || Chk(B, b, C, c, A, a))
return printf("YES\n%d %d\n", b.yy - a.yy, b.xx - a.xx), 0;
return puts("NO"), 0;
}
List of Primes
注意到最后质数不会很大,预处理每个质数的贡献就可以开始爆搜了。
#define FIO "list"
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
const int MAXN = 2340;
LL f[MAXN][MAXN], g[MAXN][MAXN], l, r;
int n, cnt, now, p[MAXN], v[MAXN], use[MAXN];
bool chk[MAXN];
char ch[MAXN];
inline void Init()
{
for (int i = 2; i < MAXN; i ++)
{
if (!chk[i])
p[++ n] = i;
for (int j = 1; i * p[j] < MAXN; j ++)
{
chk[i * p[j]] = 1;
if (i % p[j] == 0)
break;
}
}
}
inline void Print(LL l, LL r)
{
int tot = 0, cur;
ch[++ tot] = '[';
for (int i = 1, t; i <= cnt; i ++)
{
t = p[use[i]], cur = tot + v[use[i]];
while (t)
ch[cur --] = t % 10 + '0', t /= 10;
tot += v[use[i]];
ch[++ tot] = ',', ch[++ tot] = ' ';
}
ch[-- tot] = ']', ch[++ tot] = ',', ch[++ tot] = ' ';
for (LL i = l; i <= min(r, (LL)tot); i ++)
putchar(ch[i]);
}
inline void Dfs(int sum, LL l, LL r)
{
int i;
for (i = use[cnt] + 1; i <= n && p[i] < sum; i ++)
{
LL t = f[sum - p[i]][i + 1] * (now + v[i] + 2) + g[sum - p[i]][i + 1];
if (t < l)
l -= t, r -= t;
else
{
use[++ cnt] = i, now += v[i] + 2;
Dfs(sum - p[i], l, r);
cnt --, now -= v[i] + 2;
l = 1, r -= t;
if (r <= 0)
return ;
}
}
if (p[i] == sum)
use[++ cnt] = i, Print(l, r), cnt --;
return ;
}
int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#else
freopen(FIO".in", "r", stdin);
freopen(FIO".out", "w", stdout);
#endif
cin >> l >> r;
Init();
for (int i = 1; i <= n; i ++)
v[i] = p[i] >= 1000 ? 4 : (p[i] >= 100 ? 3 : (p[i] >= 10 ? 2 : 1)), f[p[i]][i] = 1, g[p[i]][i] = v[i] + 4;
for (int i = 2; i < MAXN; i ++)
for (int j = n; j; j --)
{
f[i][j] += f[i][j + 1];
g[i][j] += g[i][j + 1];
if (i >= p[j])
f[i][j] += f[i - p[j]][j + 1], g[i][j] += g[i - p[j]][j + 1] + f[i - p[j]][j + 1] * (v[j] + 2);
}
for (int i = 2; i < MAXN; i ++)
{
if (g[i][1] < l)
l -= g[i][1], r -= g[i][1];
else
{
Dfs(i, l, r);
l = 1, r -= g[i][1];
if (r <= 0)
return 0;
}
}
}
Mole Tunnels
暴力是费用流。
完全二叉树深度是
#define FIO "mole"
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
const int MAXN = 300005;
int n, m, c[MAXN], f[MAXN], g[MAXN], h[MAXN], p[MAXN], ans;
inline void Upd(int x)
{
f[x] = 1 << 30, p[x] = 0;
if (c[x])
f[x] = 0, p[x] = x;
if ((x << 1) <= n && f[x] > f[x << 1] + (h[x << 1] ? -1 : 1))
f[x] = f[x << 1] + (h[x << 1] ? -1 : 1), p[x] = p[x << 1];
if ((x << 1 | 1) <= n && f[x] > f[x << 1 | 1] + (h[x << 1 | 1] ? -1 : 1))
f[x] = f[x << 1 | 1] + (h[x << 1 | 1] ? -1 : 1), p[x] = p[x << 1 | 1];
}
int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#else
freopen(FIO".in", "r", stdin);
freopen(FIO".out", "w", stdout);
#endif
n = Read(), m = Read();
for (int i = 1; i <= n; i ++)
c[i] = Read();
for (int i = n; i; i --)
Upd(i);
while (m --)
{
int x = Read(), y, l, cur = 0, ret = 1 << 30;
for (int i = x; i; cur += g[i] ? -1 : 1, i >>= 1)
if (f[i] + cur < ret)
ret = f[i] + cur, l = i;
c[y = p[l]] --;
for (int i = x; i ^ l; i >>= 1)
if (g[i])
g[i] --;
else
h[i] ++;
for (int i = y; i ^ l; i >>= 1)
if (h[i])
h[i] --;
else
g[i] ++;
for (int i = x; i; i >>= 1)
Upd(i);
for (int i = y; i; i >>= 1)
Upd(i);
printf("%d\n", ans += ret);
}
}