T1 sign

题目大意:给出一棵 N 个节点的树,求所有起点为叶节点的有向路径,其 上每一条边权值和的和。N<=10000

水题。考试的时候毒瘤出题人(学长orz)把读入顺序改了一下,于是很多人爆零(包括我QAQ。

先dfs序把以$i$为根的子树大小$size[i]$和所含叶子结点个数$s[i]$求出。考虑每条边对答案的贡献。

  1.子树里的叶子结点往外走,这一部分的贡献为$s[i]*(n-size[i])*dis$

  2.子树外的叶子结点往里走,这一部分的贡献为$(sum-s[i])*size[i]*dis$,$sum$指叶子结点个数。

然后枚举边累加就好。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,ans,du[],size[],sum,root,ss[],tot;
int head[],cnt;
struct node
{
int next,to,dis;
}edge[];
struct edge
{
int from,to,dis;
}a[];
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if (ch=='-') f=-;ch=getchar();}
while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline void add(int from,int to,int dis)
{
edge[++cnt].next=head[from];
edge[cnt].to=to;
edge[cnt].dis=dis;
head[from]=cnt;
}
inline void dfs(int now,int fa)
{
size[now]=;
if (du[now]==) ss[now]=;
for (int i=head[now];i;i=edge[i].next)
{
int to=edge[i].to;
if (to==fa) continue;
a[++tot].from=now,a[tot].to=to,a[tot].dis=edge[i].dis;
dfs(to,now);
size[now]+=size[to];
ss[now]+=ss[to];
}
}
signed main()
{
n=read();
for (int i=;i<n;i++)
{
int x=read(),y=read(),z=read();
add(y,z,x);add(z,y,x);du[z]++;du[y]++;
}
for (int i=;i<=n;i++)
{
if (du[i]>) root=i;
else sum++;
}
dfs(root,);
for (int i=;i<n;i++)
ans+=ss[a[i].to]*(n-size[a[i].to])*a[i].dis+size[a[i].to]*(sum-ss[a[i].to])*a[i].dis;
printf("%lld",ans);
return ;
}

T2 map

题目大意:给定一张含有$n$个点的无向完全图,从$1$号点出发,每秒随机走一条边。$q$次询问,每次询问$t_i$秒时在点$1$的概率。

对于60%的数据,$n,q,t\leq 10^5$

对于100%的数据,$n,q,t\leq 10^{18}$

60分的很好想。设$f[i]$表示第$i$秒时在点$1$的概率,$g[i]$表示第$i$秒时不在点$1$的概率。易得到:

$f[i]=g[i-1]*\frac{1}{n-1}*(n-1)=g[i-1]$

$g[i]=f[i-1]*\frac{1}{n-1}+g[i-1]*\frac{n-2}{n-1}$

然后考试的时候就想到这里……60pts。正解只需要再往下推一步。

变换一下形式:$g[i]=g[i-2]*\frac{1}{n-1}+g[i-1]*\frac{n-2}{n-1}$

移项,得到:$g[i]-g[i-1]=-\frac{1}{n-1}*(g[i-1]-g[i-2])$

然后就是等比数列化简,得到通项公式:$g[i]=\frac{(n-1)^i-(-1)^i}{n*(n-1)^{i-1}},f[i]=\frac{(n-1)^{i-1}-(-1)^i}{n*(n-1)^{i-1}}$

最后快速幂求逆元就好。注意要$n$要模$mod$。时间复杂度$O(q\log n)$。

代码:

#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
const int mod=;
int n,t,q;
inline int qpow(int x,int y)
{
int res=;x%=mod;
while(y>){
if (y%==) res=res*x%mod;res%=mod;
x=x*x%mod;
y>>=;
}
return res%mod;
}
signed main()
{
scanf("%lld%lld",&n,&q);n%=mod;
while(q--)
{
scanf("%lld",&t);
if (t==){
printf("1\n");
continue;
}
int x=qpow(n-,t-)%mod;
if (t&) printf("%lld\n",((x-)%mod*qpow(n*x,mod-)%mod)%mod);
else printf("%lld\n",((x+)%mod*qpow(x*n,mod-)%mod)%mod);
}
return ;
}

T3 【PA2011】Journeys

题目链接

题目大意:点从$1-n$标号。给定$[l1,r1]$和$[l2,r2]$,表示$[l1,r1]$内的点与$[l2,r2]$内任意一点都有长度为$1$的边。求点$s$的单源最短路径。

线段树优化建图模板题。

建立一棵入树,一棵出树,对于每次连边建两个虚点,在其间连一条权为1的边;然后从出树连出来,连进去入树,边权均为0。注意边是双向的,因此需要做两遍。

最短路不需要 Dijkstra,只需要 01BFS。时间复杂度$O(n\log n)$。

关于各种图的优化技巧可以看大佬的博客orz

代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,S,head[],cnt,tot,dis[],ls[],rs[];
struct edge
{
int next,to,dis;
}edge[];
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if (ch=='-') f=-;ch=getchar();}
while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
return x*f;
}
void addedge(int from,int to,int dis)
{
edge[++cnt].next=head[from];
edge[cnt].to=to;
edge[cnt].dis=dis;
head[from]=cnt;
}
void Build(int &p,int &q,int l,int r) {
if(l==r){
p=l,q=l;
return ;
}
if(!p)p=++tot;
if(!q)q=++tot;
int mid=(l+r)/;
Build(ls[p],ls[q],l,mid),addedge(ls[p],p,),addedge(q,ls[q],);
Build(rs[p],rs[q],mid+,r),addedge(rs[p],p,),addedge(q,rs[q],);
}
void Add(int p,int l,int r,int x,int y,int z,int flag) {
if(x<=l&&r<=y) {
if(flag)addedge(z,p,);
else addedge(p,z,);
return ;
}
int mid=(l+r)/;
if(x<=mid)Add(ls[p],l,mid,x,y,z,flag);
if(mid<y)Add(rs[p],mid+,r,x,y,z,flag);
}
void Dijkstra() {
memset(dis,0x3f,sizeof(dis));
deque<int> q;
dis[S]=;
q.push_back(S);
while(!q.empty()) {
int now=q.front();
q.pop_front();
for(int i=head[now]; i; i=edge[i].next) {
int y=edge[i].to,v=edge[i].dis;
if(dis[y]>dis[now]+v) {
dis[y]=dis[now]+v;
if(v)q.push_back(y);
else q.push_front(y);
}
}
}
for(int i=;i<=n;i++)printf("%d\n",dis[i]);
}
int main()
{
n=read(),m=read(),S=read(),tot=n;
int root1=,root2=;
Build(root1,root2,,n);
while(m--){
int x=read(),y=read(),z=read(),w=read(),a=++tot,b=++tot;
addedge(a,b,);
Add(root1,,n,x,y,a,);
Add(root2,,n,z,w,b,);
a=++tot,b=++tot;
addedge(a,b,);
Add(root1,,n,z,w,a,);
Add(root2,,n,x,y,b,);
}
Dijkstra();
return ;
}

7月13日考试 题解(DFS序+期望+线段树优化建图)的更多相关文章

  1. bzoj5017 炸弹 (线段树优化建图+tarjan+拓扑序dp)

    直接建图边数太多,用线段树优化一下 然后缩点,记下来每个点里有多少个炸弹 然后按拓扑序反向dp一下就行了 #include<bits/stdc++.h> #define pa pair&l ...

  2. 6月28日考试 题解(GCD约分+动态规划+树状数组二维偏序)

    前言:考的一般般吧……T3暴力没打上来挺可惜的,到手的75分没了. ---------------------------------- T1 [JZOJ4745]看电影 Description 听说 ...

  3. [bzoj3073] Journeys 题解(线段树优化建图)

    Description Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建 ...

  4. bzoj3306: 树(dfs序+倍增+线段树)

    比较傻逼的一道题... 显然求子树最小值就是求出dfs序用线段树维护嘛 换根的时候树的形态不会改变,所以我们可以根据相对于根的位置分类讨论. 如果询问的x是根就直接输出整棵树的最小值. 如果询问的x是 ...

  5. [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增

    题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...

  6. bzoj2819 DFS序 + LCA + 线段树

    https://www.lydsy.com/JudgeOnline/problem.php?id=2819 题意:树上单点修改及区间异或和查询. 思维难度不高,但是题比较硬核. 整体思路是维护每一个结 ...

  7. Luogu P2982 [USACO10FEB]慢下来 Slowing down | dfs序、线段树

    题目链接 题目大意: 有一棵N个结点树和N头奶牛,一开始所有奶牛都在一号结点,奶牛们将按从编号1到编号N的顺序依次前往自己的目的地,求每头奶牛在去往自己目的地的途中将会经过多少已经有奶牛的结点. 题解 ...

  8. Codeforces Round #200 (Div. 1) D. Water Tree(dfs序加线段树)

    思路: dfs序其实是很水的东西.  和树链剖分一样, 都是对树链的hash. 该题做法是:每次对子树全部赋值为1,对一个点赋值为0,查询子树最小值. 该题需要注意的是:当我们对一棵子树全都赋值为1的 ...

  9. Codeforces 877E - Danil and a Part-time Job(dfs序+线段树)

    877E - Danil and a Part-time Job 思路:dfs序+线段树 dfs序:http://blog.csdn.net/qq_24489717/article/details/5 ...

随机推荐

  1. APP开发---后台设计

    想了好久才准备写博客的,希望能对我自己和大家都有帮助! 话不多说,直接正题! ------------------------------------------------------------- ...

  2. 记录一次dns引发的线程池故障

    # 问题描述 公司做的是一个支付系统,会对接很多第三方公司. 突然有一天,有一家第三方(简称金花平台)反应收不到我们的通知消息. # 排查过程 我们登陆自己的服务器,检查程序日志,是有给金花平台发送通 ...

  3. Alink漫谈(十) :线性回归实现 之 数据预处理

    Alink漫谈(十) :线性回归实现 之 数据预处理 目录 Alink漫谈(十) :线性回归实现 之 数据预处理 0x00 摘要 0x01 概念 1.1 线性回归 1.2 优化模型 1.3 损失函数& ...

  4. java 基本语法(一) 关键字与标识符

    1.java关键字的使用定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词)特点:关键字中所字母都为小写具体哪些关键字: 2.保留字:现Java版本尚未使用,但以后版本可能会作为关键字使用 ...

  5. 数据可视化之 图表篇(二)如何用Power BI制作疫情地图?

    丁香园制作的这个地图可视化,相信大家每天都会看好几遍,这里不讨论具体数据,仅来探讨一下PowerBI地图技术. 这个地图很简洁,主要有三个特征: 1,使用着色地图,根据数据自动配色 2,只显示中国地图 ...

  6. 机器学习实战基础(十三):sklearn中的数据预处理和特征工程(六)特征选择 feature_selection 简介

    当数据预处理完成后,我们就要开始进行特征工程了. 在做特征选择之前,有三件非常重要的事:跟数据提供者开会!跟数据提供者开会!跟数据提供者开会!一定要抓住给你提供数据的人,尤其是理解业务和数据含义的人, ...

  7. 数据可视化之分析篇(九)PowerBI数据分析实践第三弹 | 趋势分析法

    https://zhuanlan.zhihu.com/p/133484654 以财务报表分析为例,介绍通用的分析方法论,整体架构如下图所示: (点击查看大图) 我会围绕这五种不同的方法论,逐步阐述他们 ...

  8. 数据可视化之PowerQuery篇(一)空值(null)运算的的解决思路

    https://zhuanlan.zhihu.com/p/81535007 星友们在知识星球(PowerBI星球)提出的问题中,关于空值的运算经常被提及.平时接触到的源数据常常有空值,比如Excel数 ...

  9. Ethical Hacking - GAINING ACCESS(17)

    CLIENT SIDE ATTACKS - Backdooring exe' s Download an executable file first. VEIL - FRAMEWORK A backd ...

  10. C++ 线性筛素数

    今天要写一篇亲民的博客了,尽力帮助一下那些不会线性筛素数或者突然忘记线性筛素数的大佬. 众所周知,一个素数的倍数肯定不是素数(废话).所以我们可以找到一个方法,普通的筛法(其实不算筛,普通的是判断一个 ...