VK Cup 2017
来源:互联网 发布:windows如何打开war包 编辑:程序博客网 时间:2024/04/26 01:02
感觉自己代码能力太差了,这场比赛的题都调得很痛苦。。
C. Bear and Tree Jumps
对于一棵有根树来说,dfs可以得到每个节点到树根的距离。注意到跳跃距离最大为5,我们可以把距离最多分为五类,同样地,dfs出所有节点到根的距离信息。
我的解法分为两次dfs。第一次dfs可以得到节点1为树根时的距离信息。第二次dfs的目的是“换根”,也就是让每个节点以dfs序作为树根,统计与当前根节点有关的所有pair的总距离。
#include <bits/stdc++.h>using namespace std;#define ll long longconst int maxn = 200010;vector<int> E[maxn];ll dis[maxn][5];int p[maxn];ll n,k;ll ans[maxn];ll res = 0;void dfs1(int u,int pre){ dis[u][0] = 1; int len = E[u].size(); for(int i=0;i<len;i++){ int v = E[u][i]; if(v==pre)continue; p[v] = u; dfs1(v,u); ans[u] += dis[v][0]-1; ans[u] += ans[v]; for(int i=0;i<k;i++){ dis[u][i] += dis[v][(i+k-1)%k]; } }}void dfs2(int u,int pre){ int len = E[u].size(); ll tmp = ans[u]; if(u!=1)ans[u] += ans[p[u]] + dis[p[u]][0]-1; res += ans[u]; for(int i=0;i<len;i++){ int v = E[u][i]; if(v==pre)continue; ans[u] -= dis[v][0]-1; ans[u] -= ans[v]; for(int i=0;i<k;i++){ dis[u][i] -= dis[v][(i+k-1)%k]; } for(int i=0;i<k;i++){ dis[v][i] += dis[u][(i+k-1)%k]; } dfs2(v,u); for(int i=k-1;i>=0;i--){ dis[v][i] -= dis[u][(i+k-1)%k]; } for(int i=k-1;i>=0;i--){ dis[u][i] += dis[v][(i+k-1)%k]; } ans[u] += ans[v]; ans[u] += dis[v][0]-1; } ans[u] = tmp;}int main(){ cin>>n>>k; for(int i=1;i<n;i++){ int u,v; scanf("%d %d",&u,&v); E[u].push_back(v); E[v].push_back(u); } dfs1(1,0); dfs2(1,0); res += n*(n-1); cout<<res/2<<endl; return 0;}
D. Bear and Company
做这题的时候,如果只提示我是dp的话,我也会往区间分割方面想,之前没写过这种类型的dp,确实比较巧妙。因为每个位置的字符都可以往任意地方跑,于是分区间是不管用的。
容易发现除了VK以外的字符都是等效的,定义状态
#include <bits/stdc++.h>using namespace std;#define ll long longconst int maxn = 200010;vector<int> E[maxn];ll dis[maxn][5];int p[maxn];ll n,k;ll ans[maxn];ll res = 0;void dfs1(int u,int pre){ dis[u][0] = 1; int len = E[u].size(); for(int i=0;i<len;i++){ int v = E[u][i]; if(v==pre)continue; p[v] = u; dfs1(v,u); ans[u] += dis[v][0]-1; ans[u] += ans[v]; for(int i=0;i<k;i++){ dis[u][i] += dis[v][(i+k-1)%k]; } }}void dfs2(int u,int pre){ int len = E[u].size(); ll tmp = ans[u]; if(u!=1)ans[u] += ans[p[u]] + dis[p[u]][0]-1; res += ans[u]; for(int i=0;i<len;i++){ int v = E[u][i]; if(v==pre)continue; ans[u] -= dis[v][0]-1; ans[u] -= ans[v]; for(int i=0;i<k;i++){ dis[u][i] -= dis[v][(i+k-1)%k]; } for(int i=0;i<k;i++){ dis[v][i] += dis[u][(i+k-1)%k]; } dfs2(v,u); for(int i=k-1;i>=0;i--){ dis[v][i] -= dis[u][(i+k-1)%k]; } for(int i=k-1;i>=0;i--){ dis[u][i] += dis[v][(i+k-1)%k]; } ans[u] += ans[v]; ans[u] += dis[v][0]-1; } ans[u] = tmp;}int main(){ cin>>n>>k; for(int i=1;i<n;i++){ int u,v; scanf("%d %d",&u,&v); E[u].push_back(v); E[v].push_back(u); } dfs1(1,0); dfs2(1,0); res += n*(n-1); cout<<res/2<<endl; return 0;}
0 0
- VK Cup 2017
- Codeforces VK Cup 2017
- VK Cup 2017
- VK Cup 2017
- VK Cup 2017
- VK Cup 2017
- [杂题] Codeforces 772D VK Cup 2017
- [几何] Codeforces 772B VK Cup 2017
- VK CUP 2017 C String Reconstruction
- 【VK Cup 2012】final
- Codeforences #351 VK CUP
- VK Cup 2015
- Codeforces VK Cup 2015
- [Codeforces VK Cup 2016
- VK Cup 2015
- VK Cup 2015
- [数论 DAG最长路] Codeforces 772C VK Cup 2017
- [交互 点分治] Codeforces 772E VK Cup 2017
- 关于图的题
- 如何恢复非活动邮箱
- Thrift server实现的比较
- 使用nodejs搭建你自己的专属web聊天室
- RxJava+Retrofit登录案列
- VK Cup 2017
- hdu 1269 迷宫城堡
- 对ASP.NET程序员非常有用的85个工具
- Service服务的使用
- 忆往昔
- cin、cin.get()、cingetline()等函数的区别
- 关于OpenGL ES绘制效率问题的认识
- android系统权限大全
- 高精度加法——大数相加