Wannafly 挑战赛27

题目连接

https://www.nowcoder.com/acm/contest/215#question


A.灰魔法师

题目

题解

考虑到可能的完全平方数只有400400400多个,因此对于每种数,直接暴力枚举所有的完全平方数计算一下就可以了.

代码

#include <iostream>
#define int long long
const int N = 100007;
int a[N];
int n;
int p2[N];
int tot;
signed main() {for(int i = 1;;i++) {int a = i*i;if(a > 2*N) break;p2[tot++] = a;}std::cin >> n;for(int i = 1;i <= n;++i) {int tmp;std::cin >> tmp;a[tmp] ++;}int ans = 0;for(int i = 1;i <= 100000;++i) {if(a[i] == 0) continue;for(int j = 0;j < tot;++j) {int an = p2[j] - i;if(an < i) continue;if(an == i) ans += a[i]*(a[i]-1)/2;else if(an <= 100000)ans += a[i]*a[an];}}std::cout << ans << std::endl;
}

B.紫魔法师

题目

题解

注意到至少当存在一个奇环的情况下,一定需要333种颜色,而其他情况下只要222种颜色就足够了.

只需要用tarjan算法求其点双连通分量的大小即可.

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <stack>
#include <vector>
#define pr(x) std::cout << #x << ':' << x << std::endl
#define rep(i,a,b) for(int i = a;i <= b;++i)
const int N = 100007;
struct edge{int u,v,nxt;
}es[N<<2];
int head[N],cnt;
int vis[N],dfn[N],low[N],idx;
int v[N<<1],u[N<<1];
std::stack<int> stk;
void addedge(int u,int v) {es[cnt].u = u;es[cnt].v = v;es[cnt].nxt = head[u];head[u] = cnt++;
}
int flag;
void tarjan(int u,int fa) {dfn[u] = low[u] = ++idx;vis[u] = 1;for(int e = head[u];e != -1;e = es[e].nxt) {int v = es[e].v;if(v == fa) continue;stk.push(e);if(!vis[v]) {tarjan(v,u);if(low[u] > low[v]) low[u] = low[v];if(dfn[u] <= low[v]) {//割点int cnt = 0;while(true) {int se = stk.top();stk.pop();cnt++;if(se == e) break;}if(cnt > 1 && cnt % 2 != 0) {flag = 1;}}}else low[u] = std::min(low[u],dfn[v]);}
}
int n,m;
int main() {memset(head,-1,sizeof(head));std::ios::sync_with_stdio(false);std::cin >> n >> m;rep(i,1,m) {int u,v;std::cin >> u >> v;addedge(u,v);addedge(v,u);}tarjan(1,0);if(flag) std::cout << "3" << std::endl;else std::cout << "2" << std::endl;return 0;
}

C.蓝膜法师

题目

题解

树形dp

状态定义

定义dp[u][i]dp[u][i]dp[u][i]表示uuu子树中包含节点uuu的连通块大小为iii,且其余联通块大小均≤k\le k≤k的方案数.

注意上述定义中dp[u][0]dp[u][0]dp[u][0]是没有意义的,我们再定义dp[u][0]=∑t=1min{size[u],k}dp[u][t]dp[u][0] = \sum_{t = 1}^{min\{size[u],k\}} dp[u][t]dp[u][0]=∑t=1min{size[u],k}​dp[u][t].

转移方程的计算:

当我们要计算子树uuu的dpdpdp值的时候,其儿子节点分别为v1,v2,...,vmv_1,v_2,...,v_mv1​,v2​,...,vm​.

如果我们将通向儿子节点vvv的某条边切断,那么这个儿子对uuu节点联通块大小的贡献就没了,但是它的方案数可以取dp[v][1..k]dp[v][1..k]dp[v][1..k],这也就是我们定义dp[v][0]dp[v][0]dp[v][0]的意义所在了,很巧妙地,dp[v][0]dp[v][0]dp[v][0]就刚好等于儿子vvv对uuu的联通块贡献为000时的方案数.

那么方程就得到了

dp[u][i]=∑t1+t2+...+tm=i−1dp[v1][t1]∗dp[v2][t2]∗...∗dp[vm][tm]dp[u][i] = \sum_{t_1+t_2+...+t_m=i-1}dp[v_1][t_1]*dp[v_2][t_2]*...*dp[v_m][t_m]dp[u][i]=∑t1​+t2​+...+tm​=i−1​dp[v1​][t1​]∗dp[v2​][t2​]∗...∗dp[vm​][tm​]

最后答案就是dp[1][0]dp[1][0]dp[1][0]

实现方式

我们可以先将v1v_1v1​与uuu合并,再将v2v_2v2​与uuu合并…

代码

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
const int N = 2018;
typedef long long LL;
const LL P = 998244353;
std::vector<int> edge[N];
LL dp[N][N];
LL tmp[N];
int sz[N];
int n,k;
void dfs(int u,int fa) {sz[u] = 1;dp[u][1] = 1;for(int v : edge[u]) {if(v == fa) continue;dfs(v,u);memset(tmp,0,sizeof(tmp));for(int i = 1;i <= sz[u];++i) {for(int j = 0;j <= sz[v] && i + j <= k;++j) {tmp[i+j] = (tmp[i+j] + (dp[u][i] * dp[v][j] % P)) % P;}}for(int i = 1;i <= k;++i)dp[u][i] = tmp[i];sz[u] += sz[v];}for(int i = 1;i <= k;++i)dp[u][0] = (dp[u][0] + dp[u][i]) % P;
}
int main () {std::ios::sync_with_stdio(false);std::cin >> n >> k;for(int i = 0;i < n-1;++i) {int u,v;std::cin >> u >> v;edge[u].push_back(v);edge[v].push_back(u);}dfs(1,0);std::cout << dp[1][0] << std::endl;return 0;
}

D.绿膜法师

题目

题解

对于刚加入的数xxx来说,它与集合中其它的数字的gcdgcdgcd必然是它的约数.
那么枚举xxx的约数ddd,其它的数如果与xxx的gcd=dgcd = dgcd=d的话,那么其它的数必然也要有约数ddd.因此我们考虑维护一个数组muls[i]muls[i]muls[i],表示集合中的数是iii的倍数的有多少个数.

从大到小枚举xxx的约数ddd,然后muls[d]muls[d]muls[d]就表示与xxx的gcd=dgcd=dgcd=d的数的个数.随后枚举ddd的约数d2d_2d2​,并muls[d2]−=muls[d]muls[d2]-=muls[d]muls[d2]−=muls[d],这样的话就保证了刚刚用过的数不会重复使用(相当于容斥一下,倒序dpdpdp的感觉).依次类推,注意删掉的数在下一个数加入集合之前要加回来,恢复现场.

100000100000100000内的数最多有128128128个约数.
每个数的约数的约数个数和最大不超过2835每个数的约数的约数个数和最大不超过2835每个数的约数的约数个数和最大不超过2835
时间复杂度不会超过100000∗2835=3e8100000*2835=3e8100000∗2835=3e8.总之O(能过)O(能过)O(能过).

代码

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <queue>
#define pr(x) std::cout << #x << ':' << x << std::endl
#define rep(i,a,b) for(int i = a;i <= b;++i)
typedef long long LL;
const int N = 100007;
std::vector<int> ds[N];
LL mod_pow(LL x,LL n,LL p) {LL res = 1;while(n) {if(n&1) res = res * x % p;x = x * x % p;n >>= 1;}return res;
}
void sieve() {for(int i = 1;i <= 100000;++i) {for(int j = 1;j*j <= i;++j) {if(i % j != 0) continue;ds[i].push_back(j);if(j*j != i) ds[i].push_back(i/j);}std::sort(ds[i].begin(),ds[i].end(),[](int a,int b){return a > b;});}
}
LL muls[N];
int n;
int main() {sieve();std::ios::sync_with_stdio(false);std::cin >> n;while(n--) {LL x,k,p;std::cin >> x >> k >> p;for(auto t : ds[x])  muls[t] ++;LL ans = 0;std::queue<int> Q;for(auto t : ds[x]) {ans = (ans + muls[t]*mod_pow(t,k,p)) % p;int tmp = muls[t];Q.push(tmp);for(auto ft : ds[t]) {muls[ft] -= tmp;}}for(auto t : ds[x]) {int tmp = Q.front();Q.pop();for(auto ft : ds[t])muls[ft] += tmp;}std::cout << ans << std::endl;}return 0;
}

Wannafly 挑战赛27 题解相关推荐

  1. Wannafly挑战赛27 C蓝魔法师

    链接Wannafly挑战赛27 C蓝魔法师 给出一棵树,求有多少种删边方案,使得删后的图每个连通块大小小于等于\(k\),\(n,k\leq 2*10^3\) 假设我们正在考虑\(i\)这个子树,那么 ...

  2. Wannafly挑战赛26 题解

    Wannafly挑战赛26 题目连接 https://www.nowcoder.com/acm/contest/212#question A. 御坂网络 枚举圆心所在的位置, O ( n ) O(n) ...

  3. Wannafly挑战赛29题解

    这套题目非常有意思啊23333--话说为啥没有上条先生的呢-- 传送门 \(A\) 御坂美琴 蠢了--首先先判总共加起来等不等于\(n\),不是的话就不行 然后dfs记录\(n\)不断分下去能分成哪些 ...

  4. 牛客网 Wannafly挑战赛27 蓝魔法师

    蓝魔法师 链接: https://www.nowcoder.com/acm/contest/215/C 来源:牛客网 题目描述 "你,你认错人了.我真的,真的不是食人魔."--蓝魔 ...

  5. 牛客网比赛-Wannafly挑战赛27

    无关前置 最近同学都在打牛客网的比赛并且博主也在写一下牛客网的题,博主就去看了看,打了一场,题目质量还是非常不错的.我才不会告诉你我没开long long错了好久QWQ 212A-灰魔法师 题意简述 ...

  6. Wannafly挑战赛27: E. 黄魔法师(构造)

    链接:https://www.nowcoder.com/acm/contest/215/E 来源:牛客网 题目描述 "恕瑞玛,你的皇帝回来啦!"--黄魔法师 给出 n, k,求一个 ...

  7. Wannafly挑战赛27: C. 蓝魔法师(树形DP)

    链接:https://www.nowcoder.com/acm/contest/215/C 来源:牛客网 题目描述 "你,你认错人了.我真的,真的不是食人魔."--蓝魔法师 给出一 ...

  8. Wannafly挑战赛27: D. 绿魔法师(莫比乌斯函数)

    链接:https://www.nowcoder.com/acm/contest/215/D 来源:牛客网 题目描述 "我不知道你在说什么,因为我只是个pupil."--绿魔法师 一 ...

  9. Wannafly挑战赛27 C 蓝魔法师(树上dp)

    链接:https://ac.nowcoder.com/acm/contest/215/C 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5242 ...

最新文章

  1. FrostSulliven最新发布引领全球增长的60大技术
  2. jdbc执行sql 不支持“variant”数据类型。
  3. IDEA 设置自动导入包,以及手动导入包
  4. 啥是前端开发工程师必会的5种网页布局方法?
  5. SqlServer使用表值函数汇总
  6. SonarQube代码质量管理平台 的安装、配置与使用
  7. 德米特里:玩世不恭大冒险 for Mac(冒险游戏)
  8. 大闹天宫 页游 架设教程 自玩 单机
  9. [Opencv]实验:实现窗宽窗位调节(附源码及解析)
  10. R 语言 用黎曼和求近似 积分
  11. 学习总结7.1 Linux Rsh服务器
  12. 第十章:如何制定项目目标?
  13. pycharm运行时,浏览器闪退,直接关闭
  14. python开发框架——Django基础知识(七)
  15. line-height含义
  16. 直接解决OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.OMP:
  17. 六脚自锁开关引脚图及功能定义
  18. nftables和iptables的区别
  19. 贪吃蛇大作战撞墙不死c语言,贪吃蛇大作战无敌版
  20. 图书管理系统——UML软件课程项目

热门文章

  1. harmonyos con,鸿蒙HarmonyOS系统中的JS开发框架
  2. java使用教程——组件及事件处理——常用组件与布局
  3. ios realm 文件_iOS开发中使用Realm数据库
  4. [设计模式]合成复用原则
  5. AcWing 1113. 红与黑
  6. C++pair对组的创建
  7. 算法问题---两艘船是否有最大承载量
  8. Spring Boot 2.0新特性
  9. dft + fft(模板)
  10. P5357 【模板】AC自动机(二次加强版) fail树