Codeforces GYM 101968 A. Tree Game
差点自闭,感谢大佬帮忙找bug
题目:https://codeforces.com/gym/101968/problem/A
找树的重心+思维
找到树的重心,如果重心只有一个,以重心为根节点dfs,求各节点深度,那么任意一对节点都符合题意,只要让先手mark深度小的节点即可,其中同样深度的节点,交换位置扔符合题意,要加上dep[i]*(dep[i]-1)/2
如果重心有两个,分别以两个重心为根节点dfs,以任意一对节点都符合题意为基础(ans=n*(n-1)/2),如果两个深度相同的节点分别挂在两个不同的重心上,那么他们无法作为符合题意的一对节点,要减去这一部分,对每个重心深度相同的节点,分别加上交换节点扔符合题意的一部分,嗯就这样
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<vector>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<set>
#include<stack>
#include<map>
#include<fstream>
#include<cstdlib>
#include<ctime>
#include<list>
#include<climits>
#include<bitset>
#include<random>
using namespace std;
#define fopen freopen("input.in", "r", stdin);freopen("output.in", "w", stdout);
#define left asfdasdasdfasdfsdfasfsdfasfdas1
#define right asfdasdasdfasdfsdfasfsdfasfdas2
#define y1 asfdasdasdfasdfsdfasfsdfasfdas3
typedef long long ll;
typedef unsigned ui;
typedef long double ld;
const int dell[][]={{,},{,-},{,},{,-},{-,},{-,-},{-,},{-,-}};
ll mod=1e9+;
const ll inf=(1LL<<)-;
const int maxn=1e6+;
const int maxm=1e6+;
const double eps=1e-;
const double pi=acos(-1.0);
const int csize=;
int n,k,m,ar[maxn];
struct node{
int b,nex;
}no[maxn*];
int head[maxn],sz,mx,root;
int pre[maxn];
ll sspre[maxn];
int pre2[maxn];
ll sspre2[maxn];
void init(){
for(int i=;i<=n;i++)head[i]=-;
sz=;
}
void add(int a,int b){
no[sz].b=b;
no[sz].nex=head[a];
head[a]=sz++;
}
int dep[maxn],num[maxn];
void dfs(int u,int fa)
{
num[u]=;
if(dep[u]>mx){
mx=dep[u];
root=u;
}
for(int i=head[u];i!=-;i=no[i].nex){
int v=no[i].b;
if(v==fa)continue;
dep[v]=dep[u]+;
dfs(v,u);
num[u] += num[v];
}
}
bool findmid(int u,int& mid){
bool can=;
for(int i=head[u];i!=-;i=no[i].nex){
int v=no[i].b;
if(dep[v]==dep[u]+){
if(findmid(v,mid)){
return ;
}
can &= num[v]<(n+)/;
}
}
if(can && num[u]>=(n+)/){
mid=u;
return ;
}
else return ;
} int main()
{
//fopen
//freopen("input.in","r",stdin);
int t;scanf("%d",&t);
while(t--){
scanf("%d",&n);
init();
for(int i=;i<=n;i++){
int x;scanf("%d",&x);
add(i,x);
add(x,i);
}
mx=;root=;
dep[]=;
dfs(,-);
int mid=;
findmid(,mid);
ll ans=1LL*n*(n-)/;
if(n%== && num[mid]==n/){
int mid2=;
for(int i=head[mid];i!=-;i=no[i].nex){
if(dep[no[i].b]+==dep[mid]){
mid2=no[i].b;
break;
}
}
for(int i=;i<=n;i++)dep[i]=;
dep[mid2]=;
dfs(mid2,mid);
for(int i=;i<=n+;i++)pre[i]=pre2[i]=;
for(int i=;i<=n;i++){
if(dep[i]>)pre2[dep[i]]++;
} for(int i=;i<=n;i++)dep[i]=;
dep[mid]=;
dfs(mid,mid2);
for(int i=;i<=n;i++){
if(dep[i]>){
pre[dep[i]]++;
}
}
for(int i=;i<=n;i++){
ans -= (ll)pre[i]*pre2[i];
}
for(int i=;i<=n;i++){
ans += (ll)pre[i]*(pre[i]-)/;
ans += (ll)pre2[i]*(pre2[i]-)/;
}
}
else{
//if(fir==1609)while(1);
dep[mid]=;
dfs(mid,-);
for(int i=;i<=n+;i++)pre[i]=;
for(int i=;i<=n;i++)pre[dep[i]]++;
for(int i=;i<=n;i++){
ans += (ll)pre[i]*(pre[i]-)/;
}
}
printf("%lld\n",ans);
}
return ;
}
Codeforces GYM 101968 A. Tree Game的更多相关文章
- Codeforces 461B Appleman and Tree(木dp)
题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...
- Codeforces Gym 101252D&&floyd判圈算法学习笔记
一句话题意:x0=1,xi+1=(Axi+xi%B)%C,如果x序列中存在最早的两个相同的元素,输出第二次出现的位置,若在2e7内无解则输出-1. 题解:都不到100天就AFO了才来学这floyd判圈 ...
- Codeforces Gym 101190M Mole Tunnels - 费用流
题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...
- Codeforces Gym 101623A - 动态规划
题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减. 考虑将相邻的相等的数缩成一个数. 假设没有分成了$n$段,考虑最少能够减少多少划分 ...
- 【Codeforces Gym 100725K】Key Insertion
Codeforces Gym 100725K 题意:给定一个初始全0的序列,然后给\(n\)个查询,每一次调用\(Insert(L_i,i)\),其中\(Insert(L,K)\)表示在第L位插入K, ...
- Codeforces gym 101343 J.Husam and the Broken Present 2【状压dp】
2017 JUST Programming Contest 2.0 题目链接:Codeforces gym 101343 J.Husam and the Broken Present 2 J. Hu ...
- Codeforces 1129 E.Legendary Tree
Codeforces 1129 E.Legendary Tree 解题思路: 这题好厉害,我来复读一下官方题解,顺便补充几句. 首先,可以通过询问 \(n-1\) 次 \((S=\{1\},T=\{ ...
- Codeforces 280C Game on tree【概率DP】
Codeforces 280C Game on tree LINK 题目大意:给你一棵树,1号节点是根,每次等概率选择没有被染黑的一个节点染黑其所有子树中的节点,问染黑所有节点的期望次数 #inclu ...
- codeforces gym 100553I
codeforces gym 100553I solution 令a[i]表示位置i的船的编号 研究可以发现,应是从中间开始,往两边跳.... 于是就是一个点往两边的最长下降子序列之和减一 魔改树状数 ...
随机推荐
- MQTT协议-MQTT协议简介及协议原理
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建 ...
- UOJ#31 【UR #2】猪猪侠再战括号序列
传送门http://uoj.ac/problem/31 大家好我是来自百度贴吧的_叫我猪猪侠,英文名叫_CallMeGGBond. 我不曾上过大学,但这不影响我对离散数学.复杂性分析等领域的兴趣:尤其 ...
- UIDatePicker---iOS-Apple苹果官方文档翻译
本系列所有开发文档翻译链接地址: iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址 UIDatePicker //转载请注明出处--本文永久链接:http://www ...
- [POI2004] SZP (贪心+拓扑排序)
[问题描述] Byteotian 中央情报局(BIA) 雇佣了许多特工. 他们每个人的工作就是监视 另一名特工. Byteasar 国王需要进行一次秘密行动,所以他要挑选尽量多的信得过的特工. 但 是 ...
- HDU 2577 How to Type (字符串处理)
题目链接 Problem Description Pirates have finished developing the typing software. He called Cathy to te ...
- HDU 1372 Knight Moves (广搜)
题目链接 Problem Description A friend of you is doing research on the Traveling Knight Problem (TKP) whe ...
- ubuntu 玩转 nodejs
安装nginx 首先添加nginx_signing.key(必须,否则出错) $ wget http://nginx.org/keys/nginx_signing.key $ sudo apt-key ...
- list互转datatable 支持Nullable转换
/// <summary> /// list转datatable /// </summary> /// <param name="list">& ...
- Spring Cloud Netflix之Eureka 相关概念
为什么不应该使用ZooKeeper做服务发现 英文链接:Eureka! Why You Shouldn’t Use ZooKeeper for Service Discovery:http://www ...
- Linux 入门记录:三、Linux 文件基本操作管理
一.复制文件.目录 使用 cp 命令复制文件或目录: $ cp 源文件(夹)目标文件(夹) 常用参数: -r 递归复制整个目录树 -v 显示复制过程的详细信息 二.移动.重命名文件或目录 通过 mv ...