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的船的编号 研究可以发现,应是从中间开始,往两边跳.... 于是就是一个点往两边的最长下降子序列之和减一 魔改树状数 ...
随机推荐
- UVA 580 Critical Mass
https://vjudge.net/problem/UVA-580 题意:一堆U和L,用n个排成一排,问至少有3个U放在一起的方案数 f[i] 表示 至少有3个U放在一起的方案数 g[i] 表示没有 ...
- 多线程复习 Rlock ,Condition,Semaphore
#对于io操作来说,多线程和多进程性能差别不大 #1.通过Thread类实例化 import time import threading def get_detail_html(url): print ...
- Linux SSH 无密码登录
1. ssh-keygen -t rsa 2. scp root@ip:/root/.ssh/id_rsa.pub ./id2 3. cat id2 >> authtorized_keys ...
- Linux常用命令汇总(持续更新中)
命令 说明 注意点 cat access.log | wc -l 统计行数 awk命令可以做到同样的想过:cat access.log | awk 'END {print NR}' grep vnc ...
- webpack4.x 入门一篇足矣
前言: webpack4出了以后,一些插件变化很大,和之前的版本使用方式不一样,新手入坑,本篇将介绍如何从一开始配置webpack4的开发版本,对css,js进行编译打包合并生成md5,CSS中的图片 ...
- 表格td内容超出宽度显示... table-layout: fixed;
td宽度用百分比固定好的时候,即使设置了 white-space:nowrap;/*文本不会换行,在同一行显示*/ overflow:hidden;超出隐藏 text-overflow:ellipsi ...
- vuejs怎么在服务器部署?
通过npm run build 把生成的dist文件夹(不要上传文件夹)里的内容上传到http服务器上就可以通过 http来访问了,开发机上正常,上传以后 程序出现错误不能运行的原因99.99%的可能 ...
- vue路由-编程式导航
除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现. router.push(location, onComp ...
- Professional Linux Kernel Architecture 笔记 —— 中断处理(Part 2)【转】
转自:http://blog.163.com/vic_kk/blog/static/494705242010719483774/ Table of Contents 1 中断 1.1 中断的类型 1. ...
- STM32接口FSMC/FMC难点详解
STM32接口FSMC/FMC难点详解 转载 http://blog.sina.com.cn/s/blog_808bca130102x94k.html STM32F767的FMC将外部存储器划分为 ...