Sergey and Subway(CodeForces-1060E#513)(DFS计数,数学)

2023-11-09 18:59

本文主要是介绍Sergey and Subway(CodeForces-1060E#513)(DFS计数,数学),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 题目
  • 思路
  • 代码

前言

本题思路极为简单和巧妙!

题目

CF传送门
题目大意:
给你一个有n个节点的树,如果有原树有两点距离为2则加一条边,求修改后所有点对的距离和.
数据范围:
2 &lt; = n &lt; = 200000 2&lt;=n&lt;=200000 2<=n<=200000
样例:
i n p u t 1 input1 input1

4
1 2
1 3
1 4

o u t p u t 1 output1 output1

6

i n p u t 2 input2 input2

4
1 2
2 3
3 4

o u t p u t 2 output2 output2

7

思路

首先我们要知道不加边怎么做…
如果我们对于每个点对都进行分析的话,什么都不说, O ( n 2 ) O(n^2) O(n2)直接爆炸,
我们要把重点放到边上
在这里插入图片描述
如图,每一条边经过的次数就是:
s i z [ u ] ∗ ( S − s i z [ u ] ) siz[u]*(S-siz[u]) siz[u](Ssiz[u])
对于每一条边 O ( n ) O(n) O(n)算即可
但是加上题目条件呢?
我们可以发现,新树中两个点间距离为偶数那么直接除以二,为奇数就加1除以2,我们可以对整棵树进行黑白染色:
在这里插入图片描述
我们发现,只有异色情况距离为奇,那么答案加上黑点个数*白点个数即可,也就是加了1
最后除以二即可

代码

#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<cmath>
#include<cstdio>
#include<vector>
#include<climits>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
int read(){int f=1,x=0;char s=getchar();   while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}  while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}return x*f;
}
#define MAXN 200000
#define INF 0x3f3f3f3f
#define Mod int(1e9+7)
vector<int> G[MAXN+5];
int n,oe[MAXN+5],tsiz[MAXN+5];
void DFS(int u,int fa){tsiz[u]=1;int siz=G[u].size();for(int i=0;i<siz;i++){int v=G[u][i];if(v==fa) continue;oe[v]=!oe[u];//奇偶性分析DFS(v,u);//算子树大小tsiz[u]+=tsiz[v];}return ;
}
int main(){n=read();for(int i=1;i<n;i++){int u=read(),v=read();G[u].push_back(v),G[v].push_back(u);}DFS(1,0);LL ans=0,cnt=0;for(int i=1;i<=n;i++){if(oe[i]) cnt++;//计算答案ans+=1ll*tsiz[i]*(n-tsiz[i]);}ans+=cnt*(n-cnt);printf("%lld\n",ans/2);return 0;
}

这篇关于Sergey and Subway(CodeForces-1060E#513)(DFS计数,数学)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/378007

相关文章

uva 10014 Simple calculations(数学推导)

直接按照题意来推导最后的结果就行了。 开始的时候只做到了第一个推导,第二次没有继续下去。 代码: #include<stdio.h>int main(){int T, n, i;double a, aa, sum, temp, ans;scanf("%d", &T);while(T--){scanf("%d", &n);scanf("%lf", &first);scanf

uva 10025 The ? 1 ? 2 ? ... ? n = k problem(数学)

题意是    ?  1  ?  2  ?  ...  ?  n = k 式子中给k,? 处可以填 + 也可以填 - ,问最小满足条件的n。 e.g k = 12  - 1 + 2 + 3 + 4 + 5 + 6 - 7 = 12 with n = 7。 先给证明,令 S(n) = 1 + 2 + 3 + 4 + 5 + .... + n 暴搜n,搜出当 S(n) >=

uva 11044 Searching for Nessy(小学数学)

题意是给出一个n*m的格子,求出里面有多少个不重合的九宫格。 (rows / 3) * (columns / 3) K.o 代码: #include <stdio.h>int main(){int ncase;scanf("%d", &ncase);while (ncase--){int rows, columns;scanf("%d%d", &rows, &col

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

poj 3050 dfs + set的妙用

题意: 给一个5x5的矩阵,求由多少个由连续6个元素组成的不一样的字符的个数。 解析: dfs + set去重搞定。 代码: #include <iostream>#include <cstdio>#include <set>#include <cstdlib>#include <algorithm>#include <cstring>#include <cm

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int