Day 1 和 Day 4 鴿了,Day 2 和 Day 3 打得像 ** 一樣。
Day 2 T3 簡單數數題拿到手就化了一堆奇怪的充要條件結果就只能 dp 了,優化了很久(以爲我的充要條件很靠譜),留了 20min rush 沒寫完,遺憾離場。Day 3 T2 4K- 的 DS 題調了一個小時還沒調出來,遺憾離場。賽後 30min 才 AC
感覺這個 2020 年狀態一直不太行……經常浮躁而無法靜下來去分析一個問題試圖突破……希望,能改改吧。感覺在理論狀態下應該只有 D1T2 和 D4T2 兩個題切不掉的……但實際去考有沒有 175 + 200 + 205 + 200 都是個問題……
//先貼代碼,題解想起來再補 代碼也鴿了
D1T1
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;
int n, a[1000005][2];
PII dp[1000005][2];
PII unite(const PII& u, const PII& v)
{
if(u.first > u.second) return v;
if(v.first > v.second) return u;
return MP(min(u.first, v.first), max(u.second, v.second));
}
char ans[1000005];
int main()
{
scanf("%d", &n);
rep(i, 2) rep(j, 2 * n) scanf("%d", &a[j][i]);
dp[0][0] = MP(0, 0);
dp[0][1] = MP(1, 1);
rep1(i, 2 * n - 1) {
dp[i][0] = dp[i][1] = MP(0, -1);
rep(j, 2) rep(k, 2) if(a[i - 1][k] <= a[i][j]) dp[i][j] = unite(dp[i][j], dp[i - 1][k]);
dp[i][1].first ++;
dp[i][1].second ++;
}
int ct = -1, cs = n;
if(dp[2 * n - 1][0].first <= n && dp[2 * n - 1][0].second >= n) ct = 0;
else if(dp[2 * n - 1][1].first <= n && dp[2 * n - 1][1].second >= n) ct = 1;
if(ct == -1) {
printf("-1\n");
return 0;
}
for(int i = 2 * n - 1; i >= 0; i --) {
cs -= ct;
ans[i] = 'A' + ct;
if(i == 0) break;
int nt = -1;
if(a[i - 1][0] <= a[i][ct] && dp[i - 1][0].first <= cs && dp[i - 1][0].second >= cs) nt = 0;
else if(a[i - 1][1] <= a[i][ct] && dp[i - 1][1].first <= cs && dp[i - 1][1].second >= cs) nt = 1;
ct = nt;
}
printf("%s\n", ans);
return 0;
}
D1T2
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
int n, k;
int del[200005];
int xl[200005], yl[200005], xr[200005], yr[200005];
int permx[200005], permy[200005];
int xa[200005], ya[200005];
int sta[200005];
void occupy(int cx, int cy, int ck)
{
rep(i, n) {
if(del[i]) continue;
if(xl[i] <= cx && yl[i] <= cy && xr[i] >= cx && yr[i] >= cy) del[i] = ck;
}
}
void disocc(int ck)
{
rep(i, n) if(del[i] == ck) del[i] = 0;
}
bool s_trivial(int ck, int retx[], int rety[])
{
int xlm = -INF, xrm = INF, ylm = -INF, yrm = INF;
rep(i, n) {
if(del[i]) continue;
xlm = max(xlm, xl[i]);
xrm = min(xrm, xr[i]);
ylm = max(ylm, yl[i]);
yrm = min(yrm, yr[i]);
}
if(xlm == -INF) return true;
if(ck == 0) return false;
if(xlm <= xrm) {
int cnt = 0, cr = INF;
for(int i = n - 1; i >= 0; i --) {
int cur = permy[i];
if(del[cur]) continue;
if(cr > yr[cur]) {
cr = yl[cur];
retx[cnt] = xlm;
rety[cnt] = cr;
cnt ++;
}
}
return cnt <= ck;
} else if(ylm <= yrm) {
int cnt = 0, cr = INF;
for(int i = n - 1; i >= 0; i --) {
int cur = permx[i];
if(del[cur]) continue;
if(cr > xr[cur]) {
cr = xl[cur];
retx[cnt] = cr;
rety[cnt] = ylm;
cnt ++;
}
}
return cnt <= ck;
} else if(ck == 1) return false;
occupy(xlm, ylm, ck);
retx[0] = xlm;
rety[0] = ylm;
if(s_trivial(ck - 1, retx + 1, rety + 1)) return true;
disocc(ck);
occupy(xlm, yrm, ck);
retx[0] = xlm;
rety[0] = yrm;
if(s_trivial(ck - 1, retx + 1, rety + 1)) return true;
disocc(ck);
occupy(xrm, ylm, ck);
retx[0] = xrm;
rety[0] = ylm;
if(s_trivial(ck - 1, retx + 1, rety + 1)) return true;
disocc(ck);
occupy(xrm, yrm, ck);
retx[0] = xrm;
rety[0] = yrm;
if(s_trivial(ck - 1, retx + 1, rety + 1)) return true;
disocc(ck);
return false;
}
int xs[400005], ys[400005], xtot, ytot, ltot;
int rgl[4][200005], rgr[4][200005];
int ver[4][200005], vcnt;
vector<int> G[4000015];
bool vis[4000015];
int ret[2000015];
void add_edge(int x, int y, int vx, int vy)
{
G[x << 1 | vx ^ 1].push_back(y << 1 | vy);
G[y << 1 | vy ^ 1].push_back(x << 1 | vx);
}
void dfs(int v)
{
vis[v] = true;
rep(i, G[v].size()) if(!vis[G[v][i]]) dfs(G[v][i]);
if(ret[v >> 1] == -1) ret[v >> 1] = !(v & 1);
}
void s_ntrivial()
{
int xlm = -INF, xrm = INF, ylm = -INF, yrm = INF;
rep(i, n) {
xlm = max(xlm, xl[i]);
xrm = min(xrm, xr[i]);
ylm = max(ylm, yl[i]);
yrm = min(yrm, yr[i]);
}
rep(i, n) {
xs[2 * i] = xl[i];
xs[2 * i + 1] = xr[i];
}
sort(xs, xs + 2 * n);
xtot = unique(xs, xs + 2 * n) - xs;
rep(i, n) {
ys[2 * i] = yl[i];
ys[2 * i + 1] = yr[i];
}
sort(ys, ys + 2 * n);
ytot = unique(ys, ys + 2 * n) - ys;
rep(i, 4) rep(j, n) rgl[i][j] = rgr[i][j] = -1;
rep(i, n) {
int lx = xl[i] <= xrm;
int rx = xr[i] >= xlm;
int ly = yl[i] <= yrm;
int ry = yr[i] >= ylm;
if(lx + rx + ly + ry >= 3) continue;
if(lx) {
rgl[0][i] = lower_bound(ys, ys + ytot, max(yl[i], yrm)) - ys;
rgr[0][i] = lower_bound(ys, ys + ytot, min(yr[i], ylm)) - ys;
}
if(rx) {
rgl[1][i] = lower_bound(ys, ys + ytot, max(yl[i], yrm)) - ys;
rgr[1][i] = lower_bound(ys, ys + ytot, min(yr[i], ylm)) - ys;
}
if(ly) {
rgl[2][i] = lower_bound(xs, xs + xtot, max(xl[i], xrm)) - xs;
rgr[2][i] = lower_bound(xs, xs + xtot, min(xr[i], xlm)) - xs;
}
if(ry) {
rgl[3][i] = lower_bound(xs, xs + xtot, max(xl[i], xrm)) - xs;
rgr[3][i] = lower_bound(xs, xs + xtot, min(xr[i], xlm)) - xs;
}
}
ltot = max(xtot, ytot) + 1;
vcnt = 4 * ltot;
rep1(i, ytot) add_edge(i - 1, i, 1, 0);
rep1(i, ytot) add_edge(ltot + i - 1, ltot + i, 1, 0);
rep1(i, xtot) add_edge(ltot * 2 + i - 1, ltot * 2 + i, 1, 0);
rep1(i, xtot) add_edge(ltot * 3 + i - 1, ltot * 3 + i, 1, 0);
rep(i, n) {
int p0, p1;
for(p0 = 0; p0 < 4 && rgl[p0][i] == -1; p0 ++) ;
for(p1 = 3; p1 >= 0 && rgl[p1][i] == -1; p1 --) ;
if(p1 == -1) continue;
ver[p0][i] = vcnt ++;
if(p1 > p0) ver[p1][i] = vcnt ++;
add_edge(ver[p0][i], p0 * ltot + rgl[p0][i], 1, 1);
add_edge(ver[p0][i], p0 * ltot + rgr[p0][i] + 1, 1, 0);
if(p0 != -1) {
add_edge(ver[p1][i], p1 * ltot + rgl[p1][i], 1, 1);
add_edge(ver[p1][i], p1 * ltot + rgr[p1][i] + 1, 1, 0);
}
add_edge(ver[p0][i], ver[p1][i], 0, 0);
}
rep(i, vcnt) ret[i] = -1;
rep(i, vcnt * 2) if(!vis[i]) dfs(i);
rep(i, ytot + 1) if(ret[i] || i == ytot) {
xa[0] = xrm;
ya[0] = ys[max(i - 1, 0)];
break;
}
rep(i, ytot + 1) if(ret[i + ltot] || i == ytot) {
xa[1] = xlm;
ya[1] = ys[max(i - 1, 0)];
break;
}
rep(i, xtot + 1) if(ret[i + ltot * 2] || i == xtot) {
ya[2] = yrm;
xa[2] = xs[max(i - 1, 0)];
break;
}
rep(i, xtot + 1) if(ret[i + ltot * 3] || i == xtot) {
ya[3] = ylm;
xa[3] = xs[max(i - 1, 0)];
break;
}
}
template<int* arr>
bool cmp(int i, int j)
{
return arr[i] < arr[j];
}
int main()
{
scanf("%d%d", &n, &k);
rep(i, n) scanf("%d%d%d%d", &xl[i], &yl[i], &xr[i], &yr[i]);
rep(i, n) permx[i] = permy[i] = i;
sort(permx, permx + n, cmp<xl>);
sort(permy, permy + n, cmp<yl>);
rep(i, n) xa[i] = ya[i] = 1;
if(!s_trivial(k, xa, ya)) s_ntrivial();
rep(i, k) printf("%d %d\n", xa[i], ya[i]);
return 0;
}
D1T3
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;
namespace s64
{
int n, m, q;
int x[500005], y[500005];
int qt[1000005], qv[1000005];
int px[500005], perm[500005], pos[500005];
int ax[1000005], ay[1000005];
bool cmpx(int i, int j)
{
return x[i] < x[j] || x[i] == x[j] && y[i] < y[j];
}
bool cmpy(int i, int j)
{
return i == -1 ? false : (j == -1 ? true : y[i] < y[j]);
}
struct segt
{
int dat[1048576];
segt()
{
memset(dat, -1, sizeof(dat));
}
void build()
{
rep(i, m) dat[i + 524288] = perm[i];
int l = 524288, r = m + 524287;
l >>= 1; r >>= 1;
while(l > 0) {
for(int i = l; i <= r; i ++) dat[i] = cmpy(dat[i << 1], dat[i << 1 | 1]) ? dat[i << 1] : dat[i << 1 | 1];
l >>= 1;
r >>= 1;
}
}
void erase(int cur)
{
cur = pos[cur] + 524288;
dat[cur] = -1;
for(cur >>= 1; cur > 0; cur >>= 1) dat[cur] = cmpy(dat[cur << 1], dat[cur << 1 | 1]) ? dat[cur << 1] : dat[cur << 1 | 1];
}
int query(int cx)
{
int l = 524288, r = upper_bound(px, px + m, cx) - px + 524287;
int ret = -1;
while(l < r) {
if(l & 1) ret = cmpy(ret, dat[l]) ? ret : dat[l];
if(!(r & 1)) ret = cmpy(ret, dat[r]) ? ret : dat[r];
l = l + 1 >> 1;
r = r - 1 >> 1;
}
if(l == r) ret = cmpy(ret, dat[l]) ? ret : dat[l];
return ret;
}
}tre;
struct dsu
{
int pre[500005];
void init()
{
rep(i, m) pre[i] = i;
}
int root(int x)
{
return pre[x] == x ? x : pre[x] = root(pre[x]);
}
}con;
bool del[500005];
int tp[500005];
set<int> hv, hvu, hvr;
map<int, int> ver, hor;
void insert_d(map<int, int>& cur, int cv, int cdat)
{
if(cur.find(cdat) == cur.end()) cur.insert(MP(cdat, cv));
else con.pre[cv] = cur[cdat];
}
void solve()
{
rep(i, m) perm[i] = i;
sort(perm, perm + m, cmpx);
rep(i, m) pos[perm[i]] = i;
rep(i, m) px[i] = x[perm[i]];
tre.build();
con.init();
rep(i, m) del[i] = false;
rep(i, m) tp[i] = -1;
hv.clear();
hvu.clear();
hvr.clear();
ver.clear();
hor.clear();
hv.insert(-1);
hv.insert(n + 1);
rep(i, q) {
int pre, nxt;
if(qt[i] == 2) {
set<int>::iterator it = hv.lower_bound(qv[i]);
nxt = *it;
pre = *prev(it);
while(true) {
int cv = tre.query(qv[i]);
if(cv == -1 || y[cv] > n - qv[i]) break;
tre.erase(cv);
tp[cv] = 0;
insert_d(ver, cv, y[cv]);
}
if(ver.find(n - qv[i]) != ver.end()) {
int cv = ver[n - qv[i]];
del[cv] = true;
ver.erase(n - qv[i]);
}
while(true) {
map<int, int>::iterator it = hor.lower_bound(pre);
if(it == hor.end() || it->first >= qv[i]) break;
x[it->second] = qv[i];
insert_d(hor, it->second, qv[i]);
hor.erase(it);
}
map<int, int>::iterator it2 = hor.find(qv[i]);
if(it2 != hor.end() && hvu.find(qv[i]) != hvu.end()) {
del[it2->second] = true;
hor.erase(it2);
}
hv.insert(qv[i]);
hvr.insert(qv[i]);
} else if(qt[i] == 3) {
set<int>::iterator it = hv.upper_bound(qv[i]);
nxt = *it;
pre = *prev(it);
while(true) {
int cv = tre.query(qv[i]);
if(cv == -1 || y[cv] > n - qv[i]) break;
tre.erase(cv);
tp[cv] = 1;
insert_d(hor, cv, x[cv]);
}
if(hor.find(qv[i]) != hor.end()) {
int cur = hor[qv[i]];
del[cur] = true;
hor.erase(qv[i]);
}
while(true) {
map<int, int>::iterator it = ver.lower_bound(n - nxt);
if(it == ver.end() || it->first >= n - qv[i]) break;
y[it->second] = n - qv[i];
insert_d(ver, it->second, n - qv[i]);
ver.erase(it);
}
map<int, int>::iterator it2 = ver.find(n - qv[i]);
if(it2 != ver.end() && hvr.find(qv[i]) != hvr.end()) {
del[it2->second] = true;
ver.erase(it2);
}
hv.insert(qv[i]);
hvu.insert(qv[i]);
} else {
int cqv = con.root(qv[i]);
if(tp[cqv] == -1) {
ax[i] = x[cqv];
ay[i] = y[cqv];
} else if(tp[cqv]) {
ax[i] = x[cqv];
ay[i] = del[cqv] ? n - x[cqv] : n - *hv.upper_bound(x[cqv]);
} else {
ax[i] = del[cqv] ? n - y[cqv] : *prev(hv.lower_bound(n - y[cqv]));
ay[i] = y[cqv];
}
}
}
rep(i, m) if(tp[i] == -1) tre.erase(i);
rep(i, m) {
if(tp[i] == -1) continue;
int cqv = con.root(i);
if(tp[cqv]) {
x[i] = x[cqv];
y[i] = del[cqv] ? n - x[cqv] : n - *hv.upper_bound(x[cqv]);
} else {
x[i] = del[cqv] ? n - y[cqv] : *prev(hv.lower_bound(n - y[cqv]));
y[i] = y[cqv];
}
}
}
}
int n, m, q;
int x[500005], y[500005];
int qt[1000005], qv[1000005], qw[1000005];
int ax[1000005], ay[1000005];
int vid[1000005], qid[1000005], vcnt;
void deposit(int l, int r)
{
if(l == r) return;
int mid = l + r >> 1;
deposit(l, mid);
deposit(mid + 1, r);
int mv = -1;
s64::m = 0;
for(int i = l; i <= mid; i ++) {
if(qt[i] != 4) continue;
if(mv == -1) mv = vid[i];
s64::x[s64::m] = qv[i];
s64::y[s64::m] = qw[i];
s64::m ++;
}
if(mv == -1) return;
s64::q = 0;
for(int i = mid + 1; i <= r; i ++) {
if(qt[i] == 4 || qt[i] == 1 && (qv[i] < mv || qv[i] >= mv + s64::m)) continue;
s64::qt[s64::q] = qt[i];
s64::qv[s64::q] = qt[i] == 1 ? qv[i] - mv : qv[i];
qid[i] = s64::q;
s64::q ++;
}
s64::solve();
for(int i = mid + 1; i <= r; i ++) if(qt[i] == 1 && qv[i] >= mv && qv[i] < mv + s64::m) {
ax[i] = s64::ax[qid[i]];
ay[i] = s64::ay[qid[i]];
}
s64::m = 0;
for(int i = l; i <= mid; i ++) {
if(qt[i] != 4) continue;
qv[i] = s64::x[s64::m];
qw[i] = s64::y[s64::m];
s64::m ++;
}
}
int main()
{
scanf("%d%d%d", &n, &m, &q);
rep(i, m) scanf("%d%d", &x[i], &y[i]);
vcnt = m;
rep(i, q) {
scanf("%d%d", &qt[i], &qv[i]);
if(qt[i] == 4) {
scanf("%d", &qw[i]);
vid[i] = vcnt ++;
}
}
rep(i, q) if(qt[i] == 1) qv[i] --;
else if(qt[i] == 2) qv[i] = n - qv[i];
s64::n = n;
s64::m = m;
s64::q = 0;
rep(i, m) {
s64::x[i] = x[i];
s64::y[i] = y[i];
}
rep(i, q) {
if(qt[i] == 4 || qt[i] == 1 && qv[i] >= m) continue;
s64::qt[s64::q] = qt[i];
s64::qv[s64::q] = qv[i];
qid[i] = s64::q;
s64::q ++;
}
s64::solve();
rep(i, q) if(qt[i] == 1 && qv[i] < m) {
ax[i] = s64::ax[qid[i]];
ay[i] = s64::ay[qid[i]];
}
deposit(0, q - 1);
rep(i, q) if(qt[i] == 1) printf("%d %d\n", ax[i], ay[i]);
return 0;
}
D2T1
#include "chameleon.h"
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;
int n;
vector<int> G[1005];
int rt[1005], xval[1005];
bool ban[1005][1005];
void add_edge(int u, int v)
{
G[u].push_back(v);
G[v].push_back(u);
int nxv = xval[u] ^ xval[v] ^ 1;
int cu = rt[u], cv = rt[v];
rep1(i, 2 * n) if(rt[i] == cu) {
rt[i] = cv;
xval[i] ^= nxv;
}
}
bool check(int x, int l, int r, int tp)
{
vector<int> cq;
cq.push_back(x);
for(int i = l; i <= r; i ++)
if(xval[i] == tp) cq.push_back(i);
return Query(cq) + 1 <= cq.size();
}
bool check3(int a, int b, int c)
{
vector<int> cq;
cq.push_back(a);
cq.push_back(b);
cq.push_back(c);
return Query(cq) == 1;
}
int query_pr(int x, int l, int r, int tp)
{
if(l > r || !check(x, l, r, tp)) return -1;
while(l < r) {
int mid = l + r >> 1;
if(check(x, mid + 1, r, tp)) l = mid + 1;
else r = mid;
}
return r;
}
void Solve(int N)
{
n = N;
rep1(i, 2 * n) rep1(j, 2 * n) ban[i][j] = false;
rep1(i, 2 * n) {
rt[i] = i;
xval[i] = 0;
}
rep1(i, 2 * n) {
int cr = i - 1;
vector<int> hv;
while(true) {
cr = query_pr(i, 1, cr, 0);
if(cr == -1) break;
hv.push_back(cr);
cr --;
}
cr = i - 1;
while(true) {
cr = query_pr(i, 1, cr, 1);
if(cr == -1) break;
hv.push_back(cr);
cr --;
}
rep(j, hv.size()) add_edge(i, hv[j]);
}
rep1(i, 2 * n) if(G[i].size() == 3) {
if(check3(i, G[i][0], G[i][1])) ban[i][G[i][2]] = ban[G[i][2]][i] = true;
else if(check3(i, G[i][0], G[i][2])) ban[i][G[i][1]] = ban[G[i][1]][i] = true;
else ban[i][G[i][0]] = ban[G[i][0]][i] = true;
}
rep1(i, 2 * n) if(!xval[i])
rep(j, G[i].size()) if(!ban[i][G[i][j]]) Answer(i, G[i][j]);
}
D2T2
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;
int pre[100005], siz[100005];
int deg[100005], rdeg[100005];
set<int> G[100005], RG[100005], S[100005];
LL tot;
int root(int x)
{
return pre[x] == x ? x : pre[x] = root(pre[x]);
}
void add_edge(int, int);
void merge(int u, int v)
{
if(siz[u] < siz[v]) swap(u, v);
pre[v] = u;
vector<int> hv, rhv;
for(set<int>::iterator it = G[v].begin(); it != G[v].end(); it ++) hv.push_back(*it);
for(set<int>::iterator it = RG[v].begin(); it != RG[v].end(); it ++) rhv.push_back(*it);
tot += 1LL * S[u].size() * siz[v];
tot += 1LL * S[v].size() * siz[u];
for(set<int>::iterator it = S[v].begin(); it != S[v].end(); it ++) {
if(S[u].find(*it) != S[u].end()) tot -= siz[u] + siz[v];
else S[u].insert(*it);
}
S[v].clear();
siz[u] += siz[v];
rep(i, hv.size()) {
G[v].erase(hv[i]);
RG[hv[i]].erase(v);
}
rep(i, rhv.size()) {
RG[v].erase(rhv[i]);
G[rhv[i]].erase(v);
}
rep(i, hv.size()) add_edge(u, hv[i]);
rep(i, rhv.size()) add_edge(rhv[i], u);
}
void add_edge(int u, int v)
{
u = root(u);
v = root(v);
if(u == v) return;
if(G[u].find(v) != G[u].end()) return;
if(G[v].find(u) != G[v].end()) {
merge(u, v);
return;
}
G[u].insert(v);
RG[v].insert(u);
deg[u] += siz[v];
rdeg[v] += siz[u];
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
rep1(i, n) {
pre[i] = i;
siz[i] = 1;
}
rep1(i, n) S[i].insert(i);
rep(i, m) {
int u, v;
scanf("%d%d", &u, &v);
v = root(v);
if(S[v].find(u) == S[v].end()) {
S[v].insert(u);
tot += siz[v];
}
add_edge(u, v);
printf("%lld\n", tot);
}
return 0;
}
D2T3
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 1e9 + 7;
int n, a[605];
bool inq[1205];
int dp[1205][605];
int comb[1205][605], cdp[605][605], gtot[605];
int main()
{
comb[0][0] = 1;
rep(i, 1200) rep(j, 600) {
comb[i + 1][j] = (comb[i + 1][j] + comb[i][j]) % MOD;
comb[i + 1][j + 1] = (comb[i + 1][j + 1] + comb[i][j]) % MOD;
}
cdp[0][0] = 1;
rep(i, 600) rep(j, 600) {
cdp[i + 1][j + 1] = (cdp[i + 1][j + 1] + cdp[i][j]) % MOD;
cdp[i + 1][j] = (cdp[i + 1][j] + 2LL * cdp[i][j]) % MOD;
if(j > 0) cdp[i + 1][j - 1] = (cdp[i + 1][j - 1] + cdp[i][j]) % MOD;
}
gtot[0] = 1;
rep1(i, 600) gtot[i] = 1LL * gtot[i - 1] * i % MOD;
rep(i, 601) gtot[i] = 1LL * gtot[i] * cdp[i][0] % MOD;
for(int i = 600; i >= 1; i --) gtot[i] = 1LL * gtot[i - 1] * (i + 1) % MOD;
scanf("%d", &n);
rep(i, n) scanf("%d", &a[i]);
rep(i, n) inq[a[i]] = true;
dp[2 * n][0] = 1;
int ccnt = 0;
for(int i = 2 * n; i >= 1; i --)
if(!inq[i]) {
rep(j, n + 1) {
if(dp[i][j] == 0) continue;
dp[i - 1][j] = (dp[i - 1][j] + 1LL * dp[i][j] * (j - ccnt)) % MOD;
}
ccnt ++;
} else {
rep(j, n + 1) {
if(dp[i][j] == 0) continue;
dp[i - 1][j] = (dp[i - 1][j] + dp[i][j]) % MOD;
for(int k = j + 1; k <= n; k ++) dp[i - 1][k] = (dp[i - 1][k] +
1LL * dp[i][j] * comb[2 * n - i - j - ccnt][k - j - 1] % MOD * gtot[k - j]) % MOD;
}
}
int ans = dp[0][n];
rep(i, n) ans = 1LL * ans * (MOD + 1) / 2 % MOD;
printf("%d\n", ans);
return 0;
}
D3T1
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
struct segt
{
LL dat[524288];
void add(int l, int r, LL d)
{
l += 262144; r += 262144;
while(l < r) {
if(l & 1) dat[l] += d;
if(!(r & 1)) dat[r] += d;
l = l + 1 >> 1;
r = r - 1 >> 1;
}
if(l == r) dat[l] += d;
}
LL query(int x)
{
LL ret = 0;
for(x += 262144; x > 0; x >>= 1) ret += dat[x];
return ret;
}
}tre;
int n, a[200005];
int m, x[200005], y[200005], c[200005];
int par[200005];
int pre[200005][18];
vector<int> T[200005];
int dfn[200005], dfo[200005], tot;
vector<PII> qs[200005];
LL dp[200005];
int sta[100005], ssiz;
void gen_tre()
{
ssiz = 1;
sta[1] = -1;
rep1(i, n) {
while(a[sta[ssiz - 1]] < a[i]) ssiz --;
if(sta[ssiz] != -1) par[sta[ssiz]] = i;
par[i] = sta[ssiz - 1];
sta[ssiz ++] = i;
sta[ssiz] = -1;
}
rep1(i, n) pre[i][0] = par[i];
rep1(i, 17) rep1(j, n) pre[j][i] = pre[pre[j][i - 1]][i - 1];
rep1(i, n) T[par[i]].push_back(i);
}
int find_pre(int x, int y)
{
for(int i = 17; i >= 0; i --) if(a[pre[x][i]] < y) x = pre[x][i];
return x;
}
void dfs(int v)
{
dfn[v] = tot ++;
rep(i, T[v].size()) dfs(T[v][i]);
dfo[v] = tot - 1;
}
void gen_dp(int v)
{
rep(i, T[v].size()) {
gen_dp(T[v][i]);
dp[v] += dp[T[v][i]];
}
tre.add(dfn[v], dfn[v], dp[v]);
rep(i, T[v].size()) {
tre.add(dfn[v] + 1, dfn[T[v][i]] - 1, dp[T[v][i]]);
tre.add(dfo[T[v][i]] + 1, dfo[v], dp[T[v][i]]);
}
rep(i, qs[v].size()) dp[v] = max(dp[v], tre.query(dfn[qs[v][i].first]) + qs[v][i].second);
}
int main()
{
scanf("%d", &n);
rep1(i, n) scanf("%d", &a[i]);
a[0] = INF;
gen_tre();
scanf("%d", &m);
LL ans = 0;
rep(i, m) {
scanf("%d%d%d", &x[i], &y[i], &c[i]);
qs[find_pre(x[i], y[i])].push_back(MP(x[i], c[i]));
ans += c[i];
}
dfs(0);
gen_dp(0);
ans -= dp[0];
printf("%lld\n", ans);
return 0;
}
D3T2
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;
int n, m, l, c, q;
int a[200005], b[200005];
int pre[400005];
LL pdis[400005];
int ccnt;
bool inc[400005];
int cid[400005];
vector<int> hv[200005];
vector<int> T[400005];
int dfn[400005], dfo[400005], tot;
LL clen[200005];
LL dep[400005];
void dfs(int v, LL cd)
{
cid[v] = ccnt;
dep[v] = cd;
dfn[v] = tot ++;
rep(i, T[v].size()) {
int u = T[v][i];
dfs(u, cd + pdis[u]);
}
dfo[v] = tot - 1;
}
int deg[400005];
void gen_cyc()
{
rep(i, n + m) deg[pre[i]] ++;
queue<int> que;
rep(i, n + m) if(deg[i] == 0) que.push(i);
while(!que.empty()) {
int v = que.front();
que.pop();
T[pre[v]].push_back(v);
deg[pre[v]] --;
if(deg[pre[v]] == 0) que.push(pre[v]);
}
rep(i, n + m) if(deg[i] != 0) {
for(int j = i; deg[j] != 0; j = pre[j]) {
inc[j] = true;
hv[ccnt].push_back(j);
deg[j] = 0;
}
for(int j = hv[ccnt].size() - 1; j >= 0; j --) {
if(j != hv[ccnt].size() - 1) clen[ccnt] += pdis[hv[ccnt][j]];
dfs(hv[ccnt][j], clen[ccnt]);
}
clen[ccnt] += pdis[hv[ccnt].back()];
ccnt ++;
}
}
int qv[200005];
LL qt[200005];
LL ans[200005];
vector<int> cs[200005];
vector<int> qs[200005];
bool cmpc(int c0, int c1)
{
return dep[c0] < dep[c1] || dep[c0] == dep[c1] && c0 < c1;
}
bool cmpq(int q0, int q1)
{
return dep[qv[q0]] + qt[q0] < dep[qv[q1]] + qt[q1] || dep[qv[q0]] + qt[q0] == dep[qv[q1]] + qt[q1] && q0 < q1;
}
int cc;
int tot1;
LL tot2;
struct fwt
{
LL dat[524295];
void add(int x, LL d)
{
for(; x <= 524288; x += x & -x) dat[x] += d;
}
LL query(int x)
{
LL ret = 0;
for(; x > 0; x -= x & -x) ret += dat[x];
return ret;
}
} t3, t4;
vector<LL> rem;
void add_c(int x, int coef)
{
tot1 += coef;
tot2 += coef * (dep[x] / clen[cc]);
t3.add(lower_bound(rem.begin(), rem.end(), dep[x] % clen[cc]) - rem.begin() + 1, coef);
t4.add(dfn[x] + 1, coef);
}
LL query_q(int x, LL ct)
{
if(!inc[x]) return t4.query(dfo[x] + 1) - t4.query(dfn[x]);
LL ret = 0;
ret += tot1 * (ct / clen[cc] + 1);
ret -= tot2;
ret -= tot1 - t3.query(upper_bound(rem.begin(), rem.end(), ct % clen[cc]) - rem.begin());
ret -= t4.query(dfn[x]);
return ret;
}
void solve_q(int id)
{
cc = id;
sort(cs[id].begin(), cs[id].end(), cmpc);
sort(qs[id].begin(), qs[id].end(), cmpq);
rem.clear();
rep(i, cs[id].size()) rem.push_back(dep[cs[id][i]] % clen[cc]);
sort(rem.begin(), rem.end());
rem.resize(unique(rem.begin(), rem.end()) - rem.begin());
int j = 0;
rep(i, qs[id].size()) {
while(j < cs[id].size() && dep[cs[id][j]] <= dep[qv[qs[id][i]]] + qt[qs[id][i]]) add_c(cs[id][j ++], 1);
ans[qs[id][i]] = query_q(qv[qs[id][i]], dep[qv[qs[id][i]]] + qt[qs[id][i]]);
}
while(j > 0) add_c(cs[id][-- j], -1);
}
int main()
{
scanf("%d%d%d%d", &n, &m, &l, &c);
rep(i, n) scanf("%d", &a[i]);
rep(i, m) scanf("%d", &b[i]);
rep(i, n) {
int pos = upper_bound(a, a + n, a[i] - c % l) - a;
pdis[i] = c - c % l;
if(pos == 0) {
pdis[i] += l;
pos = upper_bound(a, a + n, a[i] + l - c % l) - a;
}
pre[i] = pos - 1;
pdis[i] += a[i] - a[pos - 1];
}
rep(i, m) {
int pos = upper_bound(a, a + n, b[i]) - a;
pdis[i + n] = 0;
if(pos == 0) {
pdis[i + n] += l;
pos = upper_bound(a, a + n, b[i] + l) - a;
}
pre[i + n] = pos - 1;
pdis[i + n] += b[i] - a[pos - 1];
}
gen_cyc();
scanf("%d", &q);
rep(i, q) {
scanf("%d%lld", &qv[i], &qt[i]);
qv[i] --;
}
rep(i, q) qs[cid[qv[i]]].push_back(i);
for(int i = n; i < n + m; i ++) cs[cid[i]].push_back(i);
rep(i, ccnt) solve_q(i);
rep(i, q) printf("%lld\n", ans[i]);
return 0;
}
D3T3
Subtask 1 Anthony
#include "Anthony.h"
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;
vector<int> G[20005];
int dis[20005];
vector<int> Mark(int n, int m, int a, int b, vector<int> u, vector<int> v)
{
rep(i, m) {
G[u[i]].push_back(v[i]);
G[v[i]].push_back(u[i]);
}
rep(i, n) dis[i] = -1;
queue<int> que;
que.push(0);
dis[0] = 0;
while(!que.empty()) {
int v = que.front();
que.pop();
rep(i, G[v].size()) {
int u = G[v][i];
if(dis[u] != -1) continue;
que.push(u);
dis[u] = dis[v] + 1;
}
}
vector<int> ret;
rep(i, m) ret.push_back(min(dis[u[i]], dis[v[i]]) % 3);
return ret;
}
Subtask 1 Catherine
#include "Catherine.h"
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;
void Init(int a, int b)
{
}
int Move(vector<int> y)
{
vector<int> hv;
rep(i, 3) if(y[i] != 0) hv.push_back(i);
if(hv.size() == 1) return hv[0];
else return hv[1] - hv[0] == 2 ? 2 : hv[0];
}
Subtask 2 Anthony
#include "Anthony.h"
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;
int dat[6] = {0, 0, 1, 1, 0, 1};
vector<PII> G[20005];
int ans[20005];
void dfs(int v, int par, int cd)
{
rep(i, G[v].size()) {
int u = G[v][i].first;
if(u == par) continue;
int nc = G[v].size() == 2 ? (cd + 1) % 6 : (dat[cd] ? 0 : 2);
ans[G[v][i].second] = dat[nc];
dfs(u, v, nc);
}
}
vector<int> Mark(int n, int m, int a, int b, vector<int> u, vector<int> v)
{
rep(i, m) {
G[u[i]].push_back(MP(v[i], i));
G[v[i]].push_back(MP(u[i], i));
}
dfs(0, -1, 0);
vector<int> ret;
rep(i, m) ret.push_back(ans[i]);
return ret;
}
Subtask 2 Catherine
#include "Catherine.h"
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;
const int dat[6] = {0, 0, 1, 1, 0, 1};
bool insm;
int pre;
int sc[5], scnt;
void Init(int a, int b)
{
insm = true;
pre = -1;
scnt = 0;
}
int getone(vector<int> cc)
{
return cc[0] ? 0 : 1;
}
int countt(vector<int> cc)
{
return cc[0] + cc[1];
}
bool isdown()
{
rep(i, 6) {
bool ok = true;
rep(j, 5) if(dat[(i + j) % 6] != sc[j]) ok = false;
if(ok) return true;
}
return false;
}
int move_up(vector<int> cc)
{
if(countt(cc) + (pre != -1) != 2) {
if(cc[0] + (pre == 0) == 1) return pre == 0 ? -1 : (pre = 0);
else return pre == 1 ? -1 : (pre = 1);
} else return cc[1] ? (pre = 1) : (pre = 0);
}
int Move(vector<int> cur)
{
if(countt(cur) + (pre != -1) != 2) insm = false;
if(!insm) return move_up(cur);
if(pre == -1) {
sc[scnt ++] = getone(cur);
cur[sc[0]] --;
}
sc[scnt ++] = getone(cur);
if(scnt == 5) {
insm = false;
if(isdown()) return -1;
else return move_up(cur);
} else return pre = sc[scnt - 1];
}
D4T1
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
int n, k, c[200005];
int occ[200005];
vector<int> G[200005];
vector<int> G0[200005];
bool del[200005];
int siz[200005];
void dfs0(int v, int par)
{
siz[v] = 1;
rep(i, G[v].size()) {
int u = G[v][i];
if(del[u] || u == par) continue;
dfs0(u, v);
siz[v] += siz[u];
}
}
int cent(int v, int par, int csiz)
{
rep(i, G[v].size()) {
int u = G[v][i];
if(del[u] || u == par) continue;
if(siz[u] > csiz / 2) return cent(u, v, csiz);
}
return v;
}
int pre[200005], vis[200005];
bool inq[200005], ing[200005];
void dfs1(int v, int par, int cid)
{
pre[v] = par;
vis[v] = cid;
inq[v] = false;
ing[c[v]] = false;
rep(i, G[v].size()) {
int u = G[v][i];
if(del[u] || u == par) continue;
dfs1(u, v, cid);
}
}
int tsolve(int v)
{
dfs1(v, -1, v);
int ret = 0;
queue<int> que;
inq[v] = true;
que.push(v);
while(!que.empty()) {
int u = que.front();
if(!ing[c[u]]) {
ing[c[u]] = true;
ret ++;
}
que.pop();
rep(i, G0[u].size()) {
int nu = G0[u][i];
if(vis[nu] != v) return INF;
while(!inq[nu]) {
inq[nu] = true;
que.push(nu);
nu = pre[nu];
}
}
}
return ret;
}
int solve(int v)
{
dfs0(v, -1);
v = cent(v, -1, siz[v]);
int ret = tsolve(v);
del[v] = true;
rep(i, G[v].size()) {
int u = G[v][i];
if(del[u]) continue;
ret = min(ret, solve(u));
}
return ret;
}
int main()
{
scanf("%d%d", &n, &k);
rep(i, n - 1) {
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
rep1(i, n) {
scanf("%d", &c[i]);
if(occ[c[i]] != 0) {
G0[occ[c[i]]].push_back(i);
G0[i].push_back(occ[c[i]]);
}
occ[c[i]] = i;
}
printf("%d\n", solve(1) - 1);
return 0;
}
D4T2
提答是不會碰的,這輩子都不會碰的
test 5 跑了 40min,屬實垃圾
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;
mt19937 rng(time(0));
int r, c;
char s[505][505];
int perm[1000005];
char cha[5] = "-|\\/";
int dx[4] = {0, -1, -1, -1}, dy[4] = {-1, 0, -1, 1};
int ret[505][505];
int occx[505][505], occy[505][505];
bool check(int i, int j, int k)
{
return s[i][j] == 'W' && s[i - dx[k]][j - dy[k]] != 'W' && s[i + dx[k]][j + dy[k]] != 'W'
&& s[i - dx[k]][j - dy[k]] != s[i + dx[k]][j + dy[k]];
}
void undo(int i, int j)
{
if(occx[i][j] == -1) return;
int ni = occx[i][j], nj = occy[i][j];
occx[ni][nj] = occy[ni][nj] = -1;
occx[ni - dx[ret[ni][nj]]][nj - dy[ret[ni][nj]]] = occy[ni - dx[ret[ni][nj]]][nj - dy[ret[ni][nj]]] = -1;
occx[ni + dx[ret[ni][nj]]][nj + dy[ret[ni][nj]]] = occy[ni + dx[ret[ni][nj]]][nj + dy[ret[ni][nj]]] = -1;
ret[ni][nj] = -1;
}
void endo(int i, int j, int k)
{
occx[i][j] = occx[i - dx[k]][j - dy[k]] = occx[i + dx[k]][j + dy[k]] = i;
occy[i][j] = occy[i - dx[k]][j - dy[k]] = occy[i + dx[k]][j + dy[k]] = j;
ret[i][j] = k;
}
int cans = -1;
char ans[505][505];
int main()
{
freopen("input_05.txt", "r", stdin);
scanf("%d%d", &r, &c);
rep(i, r) scanf("%s", s[i]);
rep(i, 4 * r * c) perm[i] = i;
rep(i, r) rep(j, c) {
ret[i][j] = -1;
occx[i][j] = occy[i][j] = -1;
}
rep(T, 100000) {
shuffle(perm, perm + 4 * r * c, rng);
rep(t, 4 * r * c) {
int i = (t >> 2) / c, j = (t >> 2) % c, k = t & 3;
if(i + dx[k] < 0 || i - dx[k] >= r) continue;
if(j - dy[k] < 0 || j + dy[k] >= c || j + dy[k] < 0 || j - dy[k] >= c) continue;
if(!check(i, j, k)) continue;
int ccnt = (occx[i][j] != -1) + (occx[i + dx[k]][j + dy[k]] != -1) + (occx[i - dx[k]][j - dy[k]] != -1)
// - (occx[i][j] == occx[i + dx[k]][j + dy[k]] && occy[i][j] == occy[i + dx[k]][j + dy[k]])
// - (occx[i][j] == occx[i - dx[k]][j - dy[k]] && occy[i][j] == occy[i - dx[k]][j - dy[k]]);
;
if(ccnt >= 2 && (rng() & 262143)) continue;
if(ccnt == 1 && (rng() & 1)) continue;
undo(i, j);
undo(i + dx[k], j + dy[k]);
undo(i - dx[k], j - dy[k]);
endo(i, j, k);
}
int tot = 0;
rep(i, r) rep(j, c) if(ret[i][j] != -1) tot ++;
if(tot > cans) {
fprintf(stderr, "new answer: %d\n", tot);
cans = tot;
rep(i, r) rep(j, c) ans[i][j] = ret[i][j] == -1 ? s[i][j] : cha[ret[i][j]];
freopen("current2.txt", "w", stdout);
rep(i, r) printf("%s\n", ans[i]);
fclose(stdout);
if(tot >= 48620) break;
}
}
return 0;
}
D4T3
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const LL INF = 0x3f3f3f3f3f3f3f3f;
int n, m;
int t[100005], l[100005], r[100005], c[100005];
int cx[100005], cy[100005], qx[100005], qy[100005];
PII xval[100005];
LL dp[100005];
int del[100005];
int cmin(int i, int j)
{
return (j == -1 || i != -1 && cy[i] < cy[j]) ? i : j;
}
struct segt
{
int dat[262144];
void build()
{
memset(dat, -1, sizeof(dat));
rep(i, m) dat[131072 | cx[i]] = i;
for(int i = 131071; i >= 0; i --) dat[i] = cmin(dat[i << 1], dat[i << 1 | 1]);
}
void erase(int x)
{
int id = 131072 | cx[x];
dat[id] = -1;
for(id >>= 1; id > 0; id >>= 1) dat[id] = cmin(dat[id << 1], dat[id << 1 | 1]);
}
int query(int x)
{
int l = 131072, r = 131072 | x;
int ret = -1;
while(l < r) {
if(l & 1) ret = cmin(ret, dat[l]);
if(!(r & 1)) ret = cmin(ret, dat[r]);
l = l + 1 >> 1;
r = r - 1 >> 1;
}
if(l == r) ret = cmin(ret, dat[l]);
return ret;
}
}tre;
int main()
{
scanf("%d%d", &n, &m);
rep(i, m) scanf("%d%d%d%d", &t[i], &l[i], &r[i], &c[i]);
rep(i, m) {
cx[i] = l[i] - t[i];
cy[i] = l[i] + t[i];
qx[i] = r[i] - t[i] + 1;
qy[i] = r[i] + t[i] + 1;
}
rep(i, m) xval[i] = MP(cx[i], i);
sort(xval, xval + m);
rep(i, m) {
cx[i] = lower_bound(xval, xval + m, MP(cx[i], i)) - xval;
qx[i] = lower_bound(xval, xval + m, MP(qx[i], m)) - xval - 1;
}
rep(i, m) dp[i] = INF;
LL ans = INF;
tre.build();
priority_queue<pair<LL, int> > que;
rep(i, m) if(l[i] == 1) {
dp[i] = c[i];
que.push(MP(-dp[i], i));
tre.erase(i);
}
while(!que.empty()) {
int v = que.top().second;
que.pop();
if(r[v] == n) {
printf("%lld\n", dp[v]);
return 0;
}
while(true) {
int i = tre.query(qx[v]);
if(i == -1 || cy[i] > qy[v]) break;
tre.erase(i);
dp[i] = dp[v] + c[i];
que.push(MP(-dp[i], i));
}
}
printf("-1\n");
return 0;
}