序列
转差分,左右来回构造一个回路。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <queue>
#include <functional>
#include <set>
#include <map>
#include <vector>
#include <iostream>
#include <limits>
#include <numeric>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int N = 300010;
int t;
ll a[N];
int main() {
#ifdef LBT
freopen("test.in", "r", stdin);
int nol_cl = clock();
#endif
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
scanf("%lld", &a[i]);
a[0] = 0;
for (int i = 1; i <= n; ++i)
a[i] += a[i - 1];
ll lst = a[n];
sort(a, a + n + 1);
ll ans = 0;
int pos1 = lower_bound(a, a + n + 1, 0LL) - a, pos2 = lower_bound(a, a + n + 1, lst) - a;
if (pos1 == pos2) ++pos2;
if (pos1 > pos2) swap(pos1, pos2);
if (pos1) {
ans = a[1] - a[0];
for (int i = 0; i + 2 <= pos1; ++i)
ans = max(ans, a[i + 2] - a[i]);
}
if (pos2 < n) {
ans = max(ans, a[n] - a[n - 1]);
for (int i = pos2; i + 2 <= n; ++i)
ans = max(ans, a[i + 2] - a[i]);
}
if (pos2 - pos1 == 1) {
if (pos1 && pos2 < n) ans = max(ans, a[pos2 + 1] - a[pos1 - 1]);
else {
if (pos1) ans = max(ans, a[pos2] - a[pos1 - 1]);
if (pos2 < n) ans = max(ans, a[pos2 + 1] - a[pos1]);
}
} else {
for (int i = pos1 + 1; i + 1 < pos2; ++i)
ans = max(ans, a[i + 1] - a[i]);
if (pos1) ans = max(ans, a[pos1 + 1] - a[pos1 - 1]);
else ans = max(ans, a[pos1 + 1] - a[pos1]);
if (pos2 < n) ans = max(ans, a[pos2 + 1] - a[pos2 - 1]);
else ans = max(ans, a[pos2] - a[pos2 - 1]);
}
printf("%lld\n", ans);
}
#ifdef LBT
LOG("Time: %dms\n", int ((clock()
-nol_cl) / (double)CLOCKS_PER_SEC * 1000));
#endif
return 0;
}
随机
二分答案,然后发现可以根据最终结果是否变化来判断。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <queue>
#include <functional>
#include <set>
#include <map>
#include <vector>
#include <iostream>
#include <limits>
#include <numeric>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
struct E {
int v, w, x;
E* next;
};
const int N = 110, M = 210, W = 110;
int n, L;
int xs[N];
double dp[N][N * W];
bool vis[N];
E* g[N];
void adde(int u, int v, int w, int x) {
static E pool[M], *p = pool;
p->v = v;
p->w = w;
p->x = x;
p->next = g[u];
xs[u] += x;
g[u] = p;
++p;
}
double guess;
void dfs(int u) {
if (vis[u])
return;
vis[u] = true;
if (!xs[u])
return;
memset(dp[u], 0, sizeof(dp[u]));
for (E* p = g[u]; p; p = p->next) {
dfs(p->v);
for (int i = 0; i <= L - p->w; ++i)
dp[u][i] += (p->w + dp[p->v][p->w + i]) * p->x;
for (int i = L - p->w + 1; i <= L; ++i)
dp[u][i] += (p->w + guess) * p->x;
}
for (int i = 0; i <= L; ++i)
dp[u][i] = min(dp[u][i] / xs[u], u == 1 ? 1e9 : guess);
}
double check(double x) {
memset(vis, 0, sizeof(vis));
guess = x;
dfs(1);
return dp[1][0];
}
int main() {
#ifdef LBT
freopen("test.in", "r", stdin);
int nol_cl = clock();
#endif
int m;
scanf("%d%d%d", &n, &m, &L);
L = min(L, (n - 1) * 100);
while (m--) {
int u, v, w, x;
scanf("%d%d%d%d", &u, &v, &w, &x);
adde(u, v, w, x);
}
double l = 0, r = 1e9;
while ((r - l) / max(1.0, l) > 8e-10) {
double mid = (l + r) / 2;
double val = check(mid);
if (val < mid)
r = val;
else
l = val;
}
printf("%.10f\n", l);
#ifdef LBT
LOG("Time: %dms\n", int ((clock()
-nol_cl) / (double)CLOCKS_PER_SEC * 1000));
#endif
return 0;
}
计数
裸的 Burnside
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <queue>
#include <functional>
#include <set>
#include <map>
#include <vector>
#include <iostream>
#include <limits>
#include <numeric>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int P = 998244353;
const int N = 52;
int n, w1, w2, w3, ans;
int fac[N], ifac[N], inv[N], cnt[N], arr[N];
int lcmTable[N][N][N];
int powTable[3][N * N * N];
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int lcm(int a, int b) { return a / gcd(a, b) * b; }
int norm(int x) { return x >= P ? x - P : x; }
void add(int& x, int y) {
if ((x += y) >= P) x -= P;
}
void sub(int& x, int y) {
if ((x -= y) < 0) x += P;
}
int mpow(int x, int k) {
int ret = 1;
while (k) {
if (k & 1)
ret = ret * (ll)x % P;
x = x * (ll)x % P;
k >>= 1;
}
return ret;
}
void dfs(int sum, int curMax, int curCon, int k) {
if (sum == 0) {
add(ans, curCon);
return;
}
for (int i = 1; i <= curMax; ++i) {
int tmp = curCon * (ll)inv[i] % P * inv[++cnt[i]] % P;
arr[k] = i;
tmp = tmp * (ll)w1 % P;
int d2 = i - 1, d3 = (i - 1) * i;
for (int j = 0; j < k; ++j) {
int g = i * arr[j] / lcmTable[i][arr[j]][1];
d2 += g * 2;
d3 += g * (i * 3 + arr[j] * 3 - 2);
for (int l = 0; l < j; ++l)
d3 += i * arr[j] * arr[l] / lcmTable[i][arr[j]][arr[l]] * 6;
}
tmp = tmp * (ll)powTable[1][d2] % P * powTable[2][d3] % P;
dfs(sum - i, min(sum - i, i), tmp, k + 1);
--cnt[i];
}
}
int main() {
#ifdef LBT
freopen("test.in", "r", stdin);
int nol_cl = clock();
#endif
scanf("%d%d%d%d", &n, &w1, &w2, &w3);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
for (int k = 1; k <= n; ++k)
lcmTable[i][j][k] = lcm(lcm(i, j), k);
powTable[0][1] = w1;
powTable[1][1] = w2;
powTable[2][1] = w3;
for (int i = 0; i < 3; ++i) {
powTable[i][0] = 1;
for (int j = 2; j <= n * n * n; ++j)
powTable[i][j] = powTable[i][j - 1] * (ll) powTable[i][1] % P;
}
fac[0] = 1;
for (int i = 1; i <= n; ++i) fac[i] = fac[i - 1] * (ll)i % P;
inv[1] = 1;
for (int i = 2; i <= n; ++i) inv[i] = -(P / i) * (ll)inv[P % i] % P + P;
ifac[0] = 1;
for (int i = 1; i <= n; ++i) ifac[i] = ifac[i - 1] * (ll)inv[i] % P;
dfs(n, n, 1, 0);
printf("%d\n", ans);
#ifdef LBT
LOG("Time: %dms\n", int ((clock()
-nol_cl) / (double)CLOCKS_PER_SEC * 1000));
#endif
return 0;
}