Tokitsukaze, CSL and Palindrome Game
Lady Layton and Stone Game
Tokitsukaze and Colorful Tree
1 0 5 10^5 105 的区间,显然不能用两个for把所有的区间和求出来,
将每个前缀和 % p \% p %p,如果前缀和 sum[i] = sum[ i前面某个位置 k]
,
说明 a[k]+a[k+1]+…+a[i] 是 p 的倍数,是可以合并的一个区间,
dp找答案最大值
#include
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
int a[N], sum[N], dp[N], pre[N];
int n, m, k;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T;
cin >> T;
while (T--) {
cin >> n >> m;
memset(dp, 0, sizeof dp);
memset(pre, 0, sizeof pre);
for (int i = 1; i <= n; i++) {
cin >> a[i];
a[i] %= m;
sum[i] = ((ll) sum[i - 1] + a[i]) % m;
dp[i] = dp[i - 1];
if (pre[sum[i]] || (pre[sum[i]] == 0 && sum[i] == 0))
dp[i] = max(dp[i], dp[pre[sum[i]]] + 1);
pre[sum[i]] = i;
}
cout << dp[n] << endl;
}
return 0;
}
官方题解
( 1 + n x 1 y 1 + m x 1 y 2 ) (1+nx^1y^1+mx^1y^2) (1+nx1y1+mx1y2)
要么选n个人中的一个,要么选m个人中的一个,要么谁都不选
其中1表示这个连通块什么人都不选
母函数 = ( 1 + x 1 ) ( 1 + x 2 ) . . . ( 1 + x n ) = 1 + k 1 x 1 + k 2 x 2 . . . + k n x n =(1+x^1)(1+x^2)...(1+x^n)=1+k_1x^1+k_2x^2...+k_nx^n =(1+x1)(1+x2)...(1+xn)=1+k1x1+k2x2...+knxn
#include
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 1e6 + 10;
int n;
// 借助x表示人数 借助y表示战斗力
// kx^ay^b 表示 a人组成战斗力为b的团队 方案总数为k
// 对于一个有n人战斗力为1 m人战斗力为2的连通块 则可以用多项式 (nxy + mxy2 + 1) 来表示
//母函数 生成函数
// 能使用的前提 幂小
struct GeneratingFunction {
ll k[4][7];// k[a][b] 最多3个人 战斗力不超过6
GeneratingFunction() {
memset(k, 0, sizeof k);
k[0][0] = 1;
}
void init() {
memset(k, 0, sizeof k);
k[0][0] = 1;
}
// 母函数乘法 正贡献01背包
void mult(ll n, ll m) {
for (int i = 3; i; i--) {
for (int j = 6; j; j--) {
k[i][j] += n * k[i - 1][j - 1] % mod;// nx^1y^1
if (j > 1)
k[i][j] += m * k[i - 1][j - 2] % mod; // mx^1y^2
k[i][j] %= mod;
}
}
}
//母函数除法 负贡献完全背包
void div(ll n, ll m) {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 6; j++) {
k[i][j] -= n * k[i - 1][j - 1] % mod;// nx^1y^1
if (j > 1)
k[i][j] -= m * k[i - 1][j - 2] % mod; // mx^1y^2
k[i][j] = (k[i][j] % mod + mod) % mod;
}
}
}
ll get() {
return (k[3][5] + k[3][6]) % mod;
}
} GF;
int a[N], b[N];
int fa[N];
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void Union(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx == fy) return;
if (fx < fy) {
fa[fy] = fx;
a[fx] += a[fy];
b[fx] += b[fy];
} else {
fa[fx] = fy;
a[fy] += a[fx];
b[fy] += b[fx];
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T;
cin >> T;
for (int cs = 1; cs <= T; cs++) {
cin >> n;
GF.init();
for (int i = 1, x; i <= n; i++) {
cin >> x;
fa[i] = i;
a[i] = b[i] = 0;
if (x == 1) a[i]++;
else b[i]++;
GF.mult(a[i], b[i]);
}
cout << GF.get() << endl;
for (int i = 1, u, v; i < n; i++) {
cin >> u >> v;
GF.div(a[find(u)], b[find(u)]);
GF.div(a[find(v)], b[find(v)]);
Union(u, v);
GF.mult(a[find(u)], b[find(v)]);
cout << GF.get() << endl;
}
}
return 0;
}
X Number
完全图上有预谋的删除k条路径,问最后最长的最短路, k ≤ 5 k\le5 k≤5, n ≤ 50 n\le50 n≤50
要删除的边一定在最短路上
#include
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1e2 + 10;
int e[N][N];
int ans = 0;
int n, m, k;
int dis[N], vis[N];
int pre[N];
int del[N][N];//del[i][j]表示点i->点j这条边被删除
void dijkstra() {
memset(pre, 0, sizeof pre);
memset(dis, INF, sizeof dis);
memset(vis, 0, sizeof vis);
dis[1] = 0;
pre[1] = 0;
for (int i = 1; i < n; i++) {
int d = INF, f = 0;
//找到当前能够找到的最短路
for (int j = 1; j <= n; j++) {
if (!vis[j] && dis[j] < d) {
d = dis[j], f = j;
}
}
vis[f] = 1;
for (int j = 1; j <= n; j++) {
if (dis[j] > dis[f] + e[f][j] && !del[f][j]) {
dis[j] = dis[f] + e[f][j];
pre[j] = f;
}
}
}
}
void dfs(int x) {
//每次都先找出一条最短路
dijkstra();
if (x == k + 1) {
ans = max(ans, dis[n]);
return;
}
// 沿着最短路 依次枚举删除的是哪一条边 直到删了k条
for (int i = n, j = pre[i]; i; i = j, j = pre[i]) {
del[i][j] = del[j][i] = 1;
dfs(x + 1);
del[i][j] = del[j][i] = 0;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T;
cin >> T;
for (int cs = 1; cs <= T; cs++) {
cin >> n >> k;
for (int i = 1, u, v, w, lim = n * (n - 1) / 2; i <= lim; i++) {
cin >> u >> v >> w;
e[u][v] = e[v][u] = w;
}
ans = 0;
dfs(1);
cout << ans << endl;
}
return 0;
}
Parentheses Matching
Play osu! on Your Tablet
Game on a Circle