[硫化铂]传染

2024-03-16 22:32
文章标签 传染 硫化

本文主要是介绍[硫化铂]传染,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

传染

题目描述

在这里插入图片描述
在这里插入图片描述

题解

可以发现,我们可以将原题转化成在一张图上选几个点,使之可以覆盖整个图。
每个点可以向与它距离不超过 r i r_i ri的点连一条单向边,使得我们选的所有点可以到达图上任意一个点。
那么我们显然可以直接将这个图建出来,然后观察一下这个图。
首先,对于一个边双联通分量中,显然任意两个点都是可以互相覆盖的,所以一个边双联通分量中最多选择一个点,我们不妨先缩一下点。
之后我们得到的就是一个拓扑图了,显然此时选择所有入度为 0 0 0的点就可以覆盖整张图,它们又不可能被别的点覆盖,所以肯定是最小的。
这样的由于总边数可能会达到 n 2 n^2 n2,所以复杂度是 O ( n 2 ) O\left(n^2\right) O(n2)

显然上面的做法是可以优化的,毕竟我们并不需要用到这么多边。
我们考虑一条从 s → t s\rightarrow t st的路径,显然,如果这条路径的长度是不超过 r s r_s rs的,那么点 s s s就会向点 t t t连边。
一条路径上肯定存在且仅存在一个点使得这个点在点分树上的整个子树能够覆盖这条路径,我们可以考虑这这个点处连接我们的这条边。
如果我们在点分树上的点 x x x上考虑点 y y y的边,如果要与点 z z z在这个点上连边,那么我们会把这个点 x x x当作我们点 y y y与点 z z z l c a lca lca
也就是说,这条路径的长度是 d e p y + d e p z − 2 d e p x dep_y+dep_z-2dep_x depy+depz2depx,当这个长度不超过 r y r_y ry时, y y y就会与 z z z连边。
调换一下顺序,也就是满足条件 r y − d e p y + d e p x ⩾ d e p z − d e p x r_y-dep_y+dep_x\geqslant dep_z-dep_x rydepy+depxdepzdepx时,会与边,如果我们固定点 x x x为当前子树的根的话,那么这两边就只与自己本身的 y y y z z z有关了。
而这种大于关系,显然可以看成一个前缀,那我们可以考虑建虚点到达这些前缀,然后 y y y就直接向这个这个虚点连边,反正覆盖是可传递的,这样就可以实现原来所有跨越这个点的边。
这样的话,我们边数就被降到 O ( n log ⁡ n ) O\left(n\log n\right) O(nlogn)级别了,不过点数还是 O ( n log ⁡ n ) O\left(n\log n\right) O(nlogn)级别的,不过还是开得下。

由于每层都要将子树内所有的点排遍序,虽然可以做些小优化,不过也不会很卡。
时间复杂度 O ( n log ⁡ 2 n ) O\left(n\log^2n\right) O(nlog2n)

源码

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define MAXN 300005
#define MAXM 6000005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long LL;
typedef unsigned long long uLL; 
typedef long double ld;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f;
const int mo=998244353;
const int mod=1e5+3;
const int inv2=499122177;
const int jzm=2333;
const int zero=2000;
const int n1=1000;
const int M=100000;
const int orG=3,ivG=332748118;
const long double Pi=acos(-1.0);
const double eps=1e-12;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){_T f=1;x=0;char s=getchar();while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
int add(int x,int y,int p){return x+y<p?x+y:x+y-p;}
void Add(int &x,int y,int p){x=add(x,y,p);}
int qkpow(int a,int s,int p){int t=1;while(s){if(s&1)t=1ll*t*a%p;a=1ll*a*a%p;s>>=1;}return t;}
int n,head[MAXN],tot,sta[MAXM],stak,ans,deg[MAXM],totp;
int dfn[MAXM],low[MAXM],belong[MAXM],idx,cnt;
int all,mx,Rt,siz[MAXN],mxson[MAXN],ord[MAXN],A[MAXN],B[MAXN];
bool vis[MAXN],insta[MAXM];
LL val[MAXN],dep[MAXN],maxx[MAXN];
vector<int>G[MAXM];
struct edge{int to,nxt;LL paid;}e[MAXN<<1];
void addEdge(int u,int v,LL w){e[++tot]=(edge){v,head[u],w};head[u]=tot;}
void getRoot(int u,int fa){siz[u]=1;mxson[u]=0;for(int i=head[u];i;i=e[i].nxt){int v=e[i].to;if(v==fa||vis[v])continue;getRoot(v,u);siz[u]+=siz[v];mxson[u]=max(mxson[u],siz[v]);}mxson[u]=max(mxson[u],all-siz[u]);if(mxson[u]<mx)Rt=u,mx=mxson[u];
}
void dosaka(int u,int fa,LL Mx,LL Mn){siz[u]=1;if(Mx<0||Mn<val[u])ord[++idx]=u;if(fa)Mx=max(Mx,val[u]),Mn=max(Mn,val[u]);for(int i=head[u];i;i=e[i].nxt){int v=e[i].to;if(v==fa||vis[v])continue;dep[v]=dep[u]+e[i].paid;dosaka(v,u,Mx-e[i].paid,Mn+e[i].paid);siz[u]+=siz[v];}
}
bool cmp1(int x,int y){return val[x]-dep[x]>val[y]-dep[y];}
bool cmp2(int x,int y){return dep[x]>dep[y];}
void sakura(int rt){mx=INF;getRoot(rt,0);dep[Rt]=idx=0;dosaka(Rt,0,-1,-1);vis[Rt]=1;int las=0,j=1;for(int i=1;i<=idx;i++)A[i]=B[i]=ord[i];sort(A+1,A+idx+1,cmp1);sort(B+1,B+idx+1,cmp2);for(int i=1;i<=idx;i++){int x=A[i];bool flag=0;while(j<=idx&&dep[x]+dep[B[j]]>val[x]){if(las)G[las].pb(B[j]),flag=1;j++;}int now=++totp;if(las)G[las].pb(now);G[x].pb(now);las=now;}while(j<=idx){if(las)G[las].pb(B[j]);j++;}for(int i=head[Rt];i;i=e[i].nxt){int v=e[i].to;if(vis[v])continue;all=siz[v];sakura(v);}
}
void tarjan(int u){dfn[u]=low[u]=++idx;sta[++stak]=u;insta[u]=1;int siz=G[u].size();for(int i=0;i<siz;i++){int v=G[u][i];if(!dfn[v])tarjan(v),low[u]=min(low[u],low[v]);else if(insta[v])low[u]=min(low[u],dfn[v]);}if(dfn[u]==low[u]){int v;cnt++;do{v=sta[stak--];insta[v]=0;belong[v]=cnt;}while(u^v);}
}
signed main(){//freopen("infect.in","r",stdin);//freopen("infect.out","w",stdout);read(n);totp=n;for(int i=1;i<=n;i++)read(val[i]);for(int i=1;i<n;i++){int u,v;LL w;read(u);read(v);read(w);addEdge(u,v,w);addEdge(v,u,w);}all=n;sakura(1);idx=0;for(int i=1;i<=totp;i++)if(!dfn[i])tarjan(i);for(int u=1;u<=totp;u++){int siz=G[u].size();for(int i=0;i<siz;i++){int v=G[u][i];if(belong[u]^belong[v])deg[belong[v]]++;}}for(int i=1;i<=cnt;i++)if(!deg[i])ans++;printf("%d\n",ans);return 0;
}

谢谢!!!

这篇关于[硫化铂]传染的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

EmotionIC:受情感惯性和传染驱动的依赖建模用于对话中情绪识别

论文地址 https://doi.org/10.1007/s11432-023-3908-6 项目代码 https://github.com/lijfrank-open/EmotionIC 关键词 对话情绪识别,情感惯性和传染,多头注意力,门控循环单元,条件随机场 研究意义 对话中情绪识别(ERC)是自然语言处理(NLP)中最受关注的研究领域之一,旨在识别对话中每个话语的情感。由于这

电子元器件选型(二):防硫化电阻

一、电阻硫化         贴片电阻的内部电极采用了银 (Ag),如果有硫黄成分气体从保护膜和电镀层之间的缝隙侵入,就会发生硫化反应,慢慢地生成硫化银 ()。由于硫化银不导电,所以随着电阻被硫化,电阻值逐渐增大,直至最终成为开路。电阻硫化之后,在电阻的电极内侧表面出现硫化银结晶。         银由于优质的导电特性,会被使用作为电极、焊接材料、电接触材料,所以在电子元器件中大量使用

1344: 【递推】【入门】流感传染

题目描述 有一批易感人群住在网格状的宿舍区内,宿舍区为n*n的矩阵,每个格点为一个房间,房间里可能住人,也可能空着。在第一天,有些房间里的人得了流感,以后每天,得流感的人会使其邻居传染上流感,(已经得病的不变),空房间不会传染。请输出第m天得流感的人数。 输入 第一行一个数字n,n不超过100,表示有n*n的宿舍房间。 接下来的n行,每行n个字符,’.’表示第一天该房间住着健康的人,’#’

[硫化铂]开心消消乐

开心消消乐 题目概述 题解 首先很容易联想到 Gym 102586J 于是我们自然而然可以想到通过建立一个dfa来处理。 但显然,我们这个dfa怎么建才是关键。 我们观察到我们每次是将三个连续的字符脱水缩合成一个字符,事实上我们每次可以将前面的两个字符当成一个函数,而最后一位当作传入函数的参数。 实际上, 我们发现,我们的每次操作相当于以最后一个数作为参数,将前面的函数不断嵌套。 而

[硫化铂]好

乐 题目概述 题解 首先, O neInDark \text\color{black}{O}\color{red}{neInDark} OneInDark:对于这种每次删一个连续段的问题,我们应该很容易想到区间dp。 首先,我们可以发现合法的连续段是呈现一个单峰的态势,即只存在一个点比 旁边的两个点都高,其它的都是在两个点的中点处。 我们可以定义 d p l , r dp_{l,r}

[硫化铂]序排速快

序排速快 题解 首先,对于原题的分割点定义,我们可以实质上是可以把它看成两个点之间的一条线。 当该线的左边数的最大值小于右边数的最小值时该分割点会成立,也就是说,之后不会有任何一个冒泡排序的范围能跨越这道分割线。 事实上,如果我们直接去统计一个分割线的出现时间的话是对计算答案没什么效果,但我们可以发现我们可以从点的层面上计算答案。 一个相当经典的技巧,我们可以计算一个点被进行了冒泡排序多

[硫化铂]密码

密码 题解 完了,居然开始阴间的密码题了。 首先的第一个想法是像 D N A DNA DNA片段一样,加几个开始码,结束码用于识别。但显然,这最多只能拿前面的 55 p t s 55pts 55pts,我们的正解最多只给我们 50 50 50个空位,显然是不行的。 这个时候,我们就可以联想到我们传统的线性变换方法用于加密了,由于我们给定的是加密串中的 k k k个位置与整个原文串,我们得

[硫化铂]膜拜大丹

膜拜大丹 题解 首先我们可以观察到一个性质,我们一定只会走二元环。 整张图是一个二分图,我们每次是从一边跳到另一边,所以走过的路径一定是一个偶环。 我们不妨记我们走过的路径为 A p 1 → B q 1 → A p 2 → B q 2 → . . . → B q n → A p n + 1 A_{p_1}\rightarrow B_{q_1}\rightarrow A_{p_2}\rig

[硫化铂]守序划分问题

守序划分问题 题目大意 题解 Province Team Selection=PTS=PtS=硫化铂,所以就叫这段时间的模拟赛题硫化铂吧。 结论题,我竟然没有想到 首先,既然是结论题,那么有结论,如果我们的一种划分所有集合方案使得 min ⁡ i ∈ S A i ⩾ max ⁡ i ∉ S A i \min_{i\in S}A_i\geqslant\max_{i\not \in S

二硫化钨/二硒化钨纳米复合材料|WSe2二硒化钨负载掺氮三维石墨烯|氮掺杂二氧化钛负载二硒化钨|二硒化钨薄片/氧化铟纳米线复合材料

二硫化钨/二硒化钨纳米复合材料|WSe2二硒化钨负载掺氮三维石墨烯|氮掺杂二氧化钛负载二硒化钨|二硒化钨薄片/氧化铟纳米线复合材料 二硫化钨/二硒化钨纳米复合材料 二维过渡金属硫族化合物(2D-TMDCs)具有独特的层状结构,可调的直接带隙、较好的柔韧性和高透光性等,在固体纳米器件、光电子器件、可穿戴设备、传感及功能薄膜等领域前景广阔。然而,如何高效的制备高品质大面积的2D-TMDCs材料一直