差点自闭,感谢大佬帮忙找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的更多相关文章

  1. Codeforces 461B Appleman and Tree(木dp)

    题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...

  2. Codeforces Gym 101252D&&floyd判圈算法学习笔记

    一句话题意:x0=1,xi+1=(Axi+xi%B)%C,如果x序列中存在最早的两个相同的元素,输出第二次出现的位置,若在2e7内无解则输出-1. 题解:都不到100天就AFO了才来学这floyd判圈 ...

  3. Codeforces Gym 101190M Mole Tunnels - 费用流

    题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...

  4. Codeforces Gym 101623A - 动态规划

    题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减. 考虑将相邻的相等的数缩成一个数. 假设没有分成了$n$段,考虑最少能够减少多少划分 ...

  5. 【Codeforces Gym 100725K】Key Insertion

    Codeforces Gym 100725K 题意:给定一个初始全0的序列,然后给\(n\)个查询,每一次调用\(Insert(L_i,i)\),其中\(Insert(L,K)\)表示在第L位插入K, ...

  6. 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 ...

  7. Codeforces 1129 E.Legendary Tree

    Codeforces 1129 E.Legendary Tree 解题思路: 这题好厉害,我来复读一下官方题解,顺便补充几句. 首先,可以通过询问 \(n-1​\) 次 \((S=\{1\},T=\{ ...

  8. Codeforces 280C Game on tree【概率DP】

    Codeforces 280C Game on tree LINK 题目大意:给你一棵树,1号节点是根,每次等概率选择没有被染黑的一个节点染黑其所有子树中的节点,问染黑所有节点的期望次数 #inclu ...

  9. codeforces gym 100553I

    codeforces gym 100553I solution 令a[i]表示位置i的船的编号 研究可以发现,应是从中间开始,往两边跳.... 于是就是一个点往两边的最长下降子序列之和减一 魔改树状数 ...

随机推荐

  1. OScached页面缓存知识总结一

    OSCache页面缓存 什么是OSCache? OSCache标记库由OpenSymphony设计,它是一种开创性的JSP定制标记应用,提供了在现有JSP页面之内实现快速内存缓冲的功能.OSCache ...

  2. webpack自动化构建你的项目

    1.读万卷书,行万里路. 2.书山有路勤为径,学海无涯苦作舟. 技术段: 相信很多刚接触前端的小伙伴,对一些自动化工具会感觉无可下手.现在前端的发展的势头,势必和后台形成一个对立面,独挡一面. 这篇文 ...

  3. static class 和 non static class 的区别

    static class non static class 1.用static修饰的是内部类,此时这个 内部类变为静态内部类:对测试有用: 2.内部静态类不需要有指向外部类的引用: 3.静态类只能访问 ...

  4. 网络设备之net_device结构与操作

    net_device结构是一个很大的结构,其中包含了硬件信息,接口信息,其他辅助信息,以及设备操作函数等: 目前仍在读代码中,后续字段注释会逐渐补充: /** * struct net_device ...

  5. ifa_local 和 ifa_address

    ifa_local 和 ifa_address区别联系: 1. 在配置了支持广播的接口上,与IFA_LOCAL一样,同样表示本地ip地址: 2. 对于点对点链路,IFA_ADDRESS表示的是对端的地 ...

  6. [device tree] interrupt mapping example

    This is for Devicetree Specification Release 0.1 Interrupt Mapping Example p19 在講解前,先帶進一些 PCI 的基礎觀念 ...

  7. 64_g3

    gimp-resynthesizer-2.0-6.20160601git787ee5a.fc2..> 11-Feb-2017 05:36 77650 gimp-save-for-web-0.29 ...

  8. 【bzoj4033】HAOI2015树上染色

    树形dp. #include<bits/stdc++.h> #define N 2010 using namespace std; typedef long long ll; ,head[ ...

  9. [LabVIEW架构]ActorFramework(二)

    前言 在上一个文章中,我们介绍了一下LabVIEW中AF的基本概念,本讲将以上一次的例子来讲解LabVIEW中的实现 正文 范例说明 假定两个人,一个作为老师,一个作为学生.学生每天早上给老师发送一封 ...

  10. [New learn]GCD的基本使用

    https://github.com/xufeng79x/GCDDemo 1.简介 介绍GCD的使用,介绍多种队列与同步异步多种情况下的组合运行情况. 2.基本使用步骤 如果使用GCD则一般也就两个步 ...