codeforces1111 简单题【DE】简要题解

news/2025/1/8 4:27:51

D

很显然可以用一个背包算出来凑齐i个位置的方案

然后总的答案就是\(dp_{n / 2}\)

然后需要扣掉不符合条件的就是把选出来的数的贡献剪掉的贡献

然后注意因为是多重集合的排列,所以需要乘上\(\frac{fac[n / 2]}{fac[cnt_a]fac[cnt_b].....}\ast \frac{fac[n / 2]}{fac[cnt_c]fac[cnt_d].....}\)

然后显然下面是所有个数的阶乘积,然后没了

#include<bits/stdc++.h>using namespace std;const int N = 1e5 + 10;
const int M = 60;
const int Mod = 1e9 + 7;int add(int a, int b) {return (a += b) >= Mod ? a - Mod : a;
}int sub(int a, int b) {return (a -= b) < 0 ? a + Mod : a;
}int mul(int a, int b) {return 1ll * a * b % Mod;
}int fast_pow(int a, int b) {int res = 1;for (; b; b >>= 1, a = mul(a, a))if (b & 1) res = mul(res, a);return res;
}int inv[N], fac[N];
int ans[M][M] = {0}, cnt[M];
int n, q, f[N];
char s[N];int id(char c) {if ('a' <= c && c <= 'z') {return c - 'a' + 27;} else {return c - 'A' + 1;}
}int C(int a, int b) {return a >= b ? mul(fac[a], mul(inv[b], inv[a - b])) : 0;
}void modify(int id, int typ) {if (typ) {for (int i = n / 2; i >= cnt[id]; i--)f[i] = add(f[i], f[i - cnt[id]]);} else {for (int i = cnt[id]; i <= n / 2; i++)f[i] = sub(f[i], f[i - cnt[id]]);}
}int main() {
#ifdef dream_makerfreopen("input.txt", "r", stdin);
#endifscanf("%s", s + 1);n = strlen(s + 1);inv[0] = fac[0] = 1;for (int i = 1; i <= n; i++)fac[i] = mul(fac[i - 1], i);inv[n] = fast_pow(fac[n], Mod - 2);for (int i = n - 1; i >= 1; i--)inv[i] = mul(inv[i + 1], i + 1);for (int i = 1; i <= n; i++)cnt[id(s[i])]++;f[0] = 1;for (int i = 1; i <= 52; i++)if (cnt[i]) modify(i, 1);for (int i = 1; i <= 52; i++) if (cnt[i] && cnt[i] <= n / 2) {modify(i, 0);ans[i][i] = f[n / 2 - cnt[i]];modify(i, 1);}for (int i = 1; i <= 52; i++) if (cnt[i]) {modify(i, 0);for (int j = 1; j <= 52; j++) if (i != j && cnt[j] && cnt[j] + cnt[i] <= n / 2) {modify(j, 0);ans[i][j] = f[n / 2 - cnt[i] - cnt[j]];modify(j, 1);}modify(i, 1);}int bas = mul(fac[n / 2], fac[n / 2]);for (int i = 1; i <= 52; i++)bas = mul(bas, inv[cnt[i]]);for (int i = 1; i <= 52; i++)for (int j = 1; j <= 52; j++)ans[i][j] = mul(ans[i][j], mul(2, bas));scanf("%d", &q);while (q--) {int x, y;scanf("%d %d", &x, &y);printf("%d\n", ans[id(s[x])][id(s[y])]);}return 0;
}

E

首先如果在虚树上考虑,我们按照深度进行dp

发现\(f_{i,j}\)表示i个点分成j个集合的方案数有转移:

\(f_{i,j}=f_{i - 1,j}\ast (j - h_i)+f_{i - 1,j - 1}\)

其中h是一个节点的父亲个数

然后h咋算呢?

就是可以用i到1的节点个数加上r到1的节点个数减去lca到1的节点个数的两倍

然后以1为根的时候每一个点在dfs序上的贡献都是一个区间,用bit算一下就可以了

然后就直接dp就可以了

因为有多次询问,所以注意边界就可以了

#include<bits/stdc++.h>using namespace std;const int N = 1e5 + 10;
const int M = 5e2 + 10;
const int LOG = 20;
const int Mod = 1e9 + 7;int add(int a, int b) {return (a += b) >= Mod ? a - Mod : a;
}int mul(int a, int b) {return 1ll * a * b % Mod;
}int n, q, f[N][M];
vector<int> g[N];
int dep[N], fa[N][LOG];
int bg[N], ed[N], ind = 0;void dfs(int u, int father) {dep[u] = dep[father] + 1;bg[u] = ++ind;fa[u][0] = father;for (int i = 1; i < 18; i++)fa[u][i] = fa[fa[u][i - 1]][i - 1];for (auto v : g[u])if (v != father)dfs(v, u);ed[u] = ind;
}int lca(int x, int y) {if (dep[x] < dep[y]) swap(x, y);int delta = dep[x] - dep[y];for (int i = 0; i < 18; i++)if ((delta >> i) & 1)x = fa[x][i];if (x == y) return x;for (int k = 17; k >= 0; k--) {if (fa[x][k] != fa[y][k]) {x = fa[x][k];y = fa[y][k];}}return fa[x][0];
}int bit[N];void modify(int t, int vl) {for (; t <= n; t += t & (-t))bit[t] += vl;
}int query(int t) {int res = 0;for (; t; t -= t & (-t))res += bit[t];return res;
}void solve() {static int h[N], p[N], k, m, r;static bool mark[N];scanf("%d %d %d", &k, &m, &r);for (int i = 1; i <= k; i++)scanf("%d", &p[i]);for (int i = 1; i <= k; i++) {modify(bg[p[i]], 1);modify(ed[p[i]] + 1, -1);mark[p[i]] = 1;}int hrt = query(bg[r]);for (int i = 1; i <= k; i++) {int g = lca(p[i], r);h[i] = query(bg[p[i]]) + hrt - 2 * query(bg[g]) + mark[g] - 1; }for (int i = 1; i <= k; i++) {modify(bg[p[i]], -1);modify(ed[p[i]] + 1, 1);mark[p[i]] = 0;}sort(h + 1, h + k + 1); // 相当于在虚树上按照深度进行dpf[0][0] = 1;for (int i = 1; i <= k; i++) {for (int j = 1; j < h[i]; j++)f[i][j] = 0;for (int j = h[i]; j <= min(i, m); j++)f[i][j] = add(mul(j - h[i], f[i - 1][j]), f[i - 1][j - 1]);}int res = 0;for (int i = 1; i <= m; i++)res = add(res, f[k][i]);printf("%d\n", res);
}int main() {
#ifdef dream_makerfreopen("input.txt", "r", stdin);
#endifscanf("%d %d", &n, &q);for (int i = 1; i < n; i++) {int u, v;scanf("%d %d", &u, &v);g[u].push_back(v);g[v].push_back(u);}dfs(1, 0);while (q--)solve();return 0;
}

转载于:https://www.cnblogs.com/dream-maker-yk/p/10359533.html

文章来源:https://blog.csdn.net/weixin_30786657/article/details/99470939
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:https://dhexx.cn/news/show-1420084.html

相关文章

Java 8 新特性 – 终极手册整理

1&#xff0e;简介 毫无疑问&#xff0c;Java 8是自Java 5&#xff08;2004年&#xff09;发布以来Java语言最大的一次版本升级&#xff0c;Java 8带来了很多的新特性&#xff0c;比如编译器、类库、开发工具和JVM&#xff08;Java虚拟机&#xff09;。在这篇教程中我们将会学…

wordpress迁移服务器指南

wordpress迁移服务器指南 标签&#xff08;空格分隔&#xff09;&#xff1a; 未分类 历经两天&#xff0c;从完全对服务器方面的内容不懂的小白终于将服务器给迁移了 打开 第一步&#xff0c;将wordpress文件&#xff0c;以及数据库导出。 打开到处的网站文件&#xff0c;第一…

域环境修改密码策略

管理工具——>组策略管理 如果想跟我一起讨论的话&#xff0c;就快加入我的知识星球吧。星球里有一千多位同样爱好安全技术的小伙伴一起交流&#xff01;知识星球 | 深度连接铁杆粉丝&#xff0c;运营高品质社群&#xff0c;知识变现的工具

iOS控制器之基类设计

题记 在进入新公司后。经过这一个月的重构项目&#xff0c;终于把项目做到了个人相对满意的程度(还有一种不满意的叫老板的需求&#xff0c;提过多次意见也没用 !)。在这次重构中按照以前的思路设计出了个人觉得比较适用的一个基类。在这里笔者会把此基类基本的设计说明一遍。 …

django数据库自动重连

2019独角兽企业重金招聘Python工程师标准>>> 简介 Django数据库连接超过wait_timeout导致连接丢失时自动重新连接数据库 https://github.com/zhanghaofei/django-db-reconnect 安装 pip install django_db_reconnect注意仅支持pymysql&#xff0c;使django使用pymys…

丁洪波 语录

完美交易 历届期货冠军王 ① 我建议只做了1-2年的&#xff0c;尽量不要满仓&#xff0c;从10%-20%的仓位开始做&#xff0c;累积经验&#xff0c;隔夜不隔夜也没关系&#xff0c;结合自己的方法。 有时候会这样&#xff0c;你满仓的时候&#xff0c;隔夜往往是相反&#xff0c;…

45个JavaScript小技巧

这篇文章的质量个人感觉一般&#xff08;有些甚至有些无厘头&#xff0c;比如第五点&#xff0c;构造函数的使用&#xff0c;直接被我去掉了&#xff09;&#xff0c; 建议过一遍就好 。 声明变量时别忘记 var 相等比较请用 而不是 undefined 、 null 、0、 false 、 NaN…

kernel input device

源码&#xff1a; android-5.0.2\linux-3.0.86\drivers\input\touchscreen\Ft5x06_ts.c 功能&#xff1a; input device驱动code&#xff0c;该篇只阐述input device驱动框架&#xff0c;其他文章将描述input子系统 1&#xff1a;注册input_device 2&#xff1a;上报事件 源码分…

WindowsServer2008R2安装Exchange Server2010

目录 安装前置环境 安装Exchange Server 2010 配置发送连接器 配置接收连接器

关于对现阶段vue项目的一些总结和感想

一、前言 现阶段手上vue的项目差不多快完了&#xff0c;空闲之余回反复对整个项目的代码结构、实现细节以及框架上的做了一些思考和优化。下面打算把想到的和重点实现的方法记录一下。 二、回顾 对于常规操作&#xff0c;这里不做过多的阐述&#xff0c;我们只讨论重点部分 1.登…