去年水平不行,导致noip滚粗,现在来复习一下,今年要小心了。
A - 小凯的疑惑
裴蜀定理。
//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 a, b;
int main()
{
gii(a, b);
printf("%lld\n", (a - 1LL) * (b - 1LL) - 1);
}
B - 时间复杂度
用个栈模拟一下。
//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;
}
void solve()
{
int L;
static char fzd[233];
gi(L);
scanf("%s", fzd + 1);
int w = 0;
if (fzd[3] == 'n') sscanf(fzd + 1, "O(n^%d)", &w);
static pair<int, char> stk[233];// (x > y : -1) (x <= y : 0) (x = c, y = n : 1)
int tp = 0;
static bool in[233];
static int mx[233];
memset(mx, 0, sizeof mx);
memset(in, 0, sizeof in);
bool flag = 1;
for (int i = 1; i <= L; ++i)
{
char ch;
while (ch = getchar(), ch != 'F' && ch != 'E');
if (ch == 'F')
{
while (ch = getchar(), ch < 'a' || ch > 'z');
static char x[10], y[10];
scanf("%s%s", x + 1, y + 1);
if (in[ch])
flag = 0;
if (!flag) continue;
in[ch] = 1;
if (x[1] == 'n' && y[1] == 'n')
{
stk[++tp] = mp(0, ch);
}
else if (x[1] == 'n' && y[1] != 'n')
{
stk[++tp] = mp(-1, ch);
}
else if (y[1] == 'n')
{
stk[++tp] = mp(1, ch);
}
else
{
int X, Y;
sscanf(x + 1, "%d", &X);
sscanf(y + 1, "%d", &Y);
if (X <= Y) stk[++tp] = mp(0, ch);
else stk[++tp] = mp(-1, ch);
}
}
else
{
if (!tp) flag = 0;
if (!flag) continue;
if (stk[tp].fi == 1) mx[tp - 1] = max(mx[tp - 1], mx[tp] + 1);
else if (stk[tp].fi == 0) mx[tp - 1] = max(mx[tp - 1], mx[tp]);
in[stk[tp].se] = 0;
mx[tp] = 0;
--tp;
}
}
if (tp || !flag)
{
puts("ERR");
return;
}
if (mx[0] == w)
{
puts("Yes");
}
else
{
//cerr << mx[0] << endl;
puts("No");
}
}
int main()
{
int T;
gi(T);
while (T--)
solve();
}
C - 逛公园
用最短路算法判断哪些点一定不会走到,先删除掉,接着建出拓扑图,如果所有没有0环是一个有向无环图,判断一下就好了。(之前还写了个智障tarjan)
//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 = 1e5 + 10, M = 2e5 + 10;
int n, m, k, p, lim;
struct edge { int to, val; edge *next; };
struct graph
{
edge e[M], *la[N], *et;
int d[N];
graph() { et = e; }
void clear() { memset(la, 0, sizeof la); et = e; }
void add(int u, int v, int w) { *++et = (edge) {v, w, la[u]}, la[u] = et; }
void dijkstra(int s)
{
memset(d, 63, sizeof d);
priority_queue<PII> pq;
pq.push(mp(0, s)); d[s] = 0;
while (!pq.empty())
{
PII x = pq.top(); pq.pop();
if (d[x.se] != -x.fi) continue;
int u = x.se;
for (edge *it = la[u]; it; it = it -> next)
{
int v = it -> to, w = it -> val;
if (d[v] > d[u] + w)
{
d[v] = d[u] + w;
pq.push(mp(-d[v], v));
}
}
}
}
} G1, G2, G;
void make_G()
{
G.clear();
static int ok[N];
int idt = 0;
memset(ok, 0, sizeof ok);
for (int i = 1; i <= n; ++i)
if (G1.d[i] + G2.d[i] <= lim + k) ok[i] = ++idt;
for (int i = 1; i <= n; ++i)
{
if (ok[i])
{
for (edge *it = G1.la[i]; it; it = it -> next)
{
if (ok[it -> to])
G.add(i, it -> to, it -> val);
}
}
}
n = idt;
}
int id[N][51];
int f[N * 51], deg[N * 51];
struct eg { int to; eg *next; };
void solve()
{
giii(n, m, k), gi(p);
G1.clear(), G2.clear();
for (int i = 1; i <= m; ++i)
{
int a, b, c;
giii(a, b, c);
G1.add(a, b, c);
G2.add(b, a, c);
}
lim = G1.d[n];
make_G();
G.dijkstra(1);
int idt = 0;
static eg e[M * 51], *la[N * 51];
eg *et = e;
for (int i = 1; i <= n; ++i)
for (int j = 0; j <= k; ++j)
id[i][j] = ++idt, la[idt] = 0, f[idt] = deg[idt] = 0;
for (int i = 1; i <= n; ++i)
{
for (edge *it = G.la[i]; it; it = it -> next)
{
int j = it -> to;
for (int l = 0; l <= k; ++l)
{
int u = id[i][l];
int dis = G.d[i] + l + (it -> val) - G.d[j];
if (dis <= k && dis >= 0)
{
int v = id[j][dis];
*++et = (eg) {v, la[u]}, la[u] = et; ++deg[v];
}
}
}
}
static int q[N * 51]; int l = 0, r = 0;
for (int i = 1; i <= idt; ++i) if (!deg[i]) q[r++] = i;
f[id[1][0]] = 1;
while (l < r)
{
int u = q[l++];
for (eg *it = la[u]; it; it = it -> next)
{
int v = it -> to;
f[v] = (f[v] + f[u]) % p;
--deg[v];
if (!deg[v]) q[r++] = v;
}
}
int ans = 0;
for (int i = 0; i <= k; ++i)
ans = (ans + f[id[n][i]]) % p;
if (r != idt)
{
puts("-1");
return;
}
printf("%d\n", ans);
}
int main()
{
int T;
gi(T);
while (T--) solve();
}