mcfx神仙的题qwq

题目链接:戳我

首先,我们知道30%的分还是挺好做的

直接枚举根,然后dfs一遍以\(O(n)\)的时间复杂度求出来有多少神仙点

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define MAXN 100010
using namespace std;
int n,t;
int a[MAXN],head[MAXN];
struct Edge{int nxt,to;}edge[MAXN<<1];
inline void add(int from,int to)
{
edge[++t].nxt=head[from],edge[t].to=to;
head[from]=t;
}
namespace subtask1
{
int ans;
int kkk[MAXN];
inline void search(int x,int pre,int maxx)
{
for(int i=head[x];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==pre) continue;
if(a[v]>maxx) kkk[v]=1;
search(v,x,max(maxx,a[v]));
}
}
inline void solve()
{
for(int p=1;p<=n;p++)
{
ans=0;
for(int i=1;i<=n;i++) kkk[i]=0;
kkk[p]=1;
search(p,0,a[p]);
for(int i=1;i<=n;i++)
if(kkk[i])
ans+=i;
printf("%d ",ans);
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
if(n<=4000) subtask1::solve();
return 0;
}

现在我们考虑正解。

对于一个点x来说,它会对哪些点产生作为神仙点的贡献?

如果x和一个点y之间可以仅通过权值小于等于\(a[x]\)的点联通,那么x一定会对点y产生贡献。

如果我们从小到大添加点,那么当添加到x的时候,x会对所有和它联通的点产生贡献。

我们用并查集的方式维护添加建树的过程。

那么每个点到根的路径上的权值和就是它的答案。

对于点权相同的点,我们不能遍历到一个就合并上去,要先记录上贡献,然后再依次合并qwq

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define MAXN 300010
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
return x*f;
}
int n,t;
int a[MAXN],h[MAXN],fa[MAXN],head[MAXN];
long long ans[MAXN],val[MAXN];
vector<pair<int,int> >G[MAXN];
struct Edge{int nxt,to;}edge[MAXN<<1];
inline void add(int from,int to)
{
edge[++t].nxt=head[from],edge[t].to=to;
head[from]=t;
}
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
inline void dfs(int x,int pre)
{
ans[x]=ans[pre]+val[x];
for(int i=head[x];i;i=edge[i].nxt)
{
int v=edge[i].to;
dfs(v,x);
}
}
inline void solve()
{
for(int i=1;i<n;i++)
{
int x=read(),y=read();
if(a[x]<a[y]) swap(x,y);
G[a[x]].push_back(make_pair(x,y));
}
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=n;i++)
{
for(int j=0;j<G[i].size();j++)
{
int x=G[i][j].first;
int y=G[i][j].second;
if(a[x]==a[y]) continue;
if(a[x]<a[y]) swap(x,y);
val[find(y)]+=x;
}
for(int j=0;j<G[i].size();j++)
{
int x=G[i][j].first;
int y=G[i][j].second;
if(a[x]<a[y]) swap(x,y);
int xx=find(x),yy=find(y);
add(xx,yy);
fa[yy]=xx;
}
}
int root=find(1);
dfs(root,0);
for(int i=1;i<=n;i++) printf("%lld ",ans[i]+i);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
n=read();
for(int i=1;i<=n;i++) a[i]=read();
solve();
return 0;
}

noi.ac #525 神树的权值的更多相关文章

  1. noi.ac #528 神树和排列

    题目链接:戳我 #include<iostream> #include<cstring> #include<cstdio> #include<algorith ...

  2. noi.ac #531 神树和物品

    题目链接:戳我 决策单调性 (蒟蒻终于会写决策单调性啦!考试全场切这题就我不会啊嘤) (证明?不会啊,自己打表看QAQ) 44pts \(O(n^2)\)代码: #include<iostrea ...

  3. noi.ac #529 神树的矩阵

    题目链接:戳我 当 \(max(n, m) \ge 3\) 时,可以如下构造: 考虑下面这样三个矩阵,红 + 蓝 − 绿得到的矩阵是一个第一行和最后一行全是 1,其他地方全是 0 的矩阵. 那么如果需 ...

  4. AC日记——联合权值 洛谷 P1351

    题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...

  5. NOIp 2014 #2 联合权值 Label:图论 !!!未AC

    题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...

  6. noi.ac上的一套(假)NOI题

    noi.ac上的一套(假)NOI题 本来想着可以刷点通过量的,结果发现好像并不是这样的. 整数 description 给你\(n,p\),要你求\(\sum_{k=1}^n\sum_{i=1}^k\ ...

  7. NOI.AC 31 MST——整数划分相关的图论(生成树、哈希)

    题目:http://noi.ac/problem/31 模拟 kruscal 的建最小生成树的过程,我们应该把树边一条一条加进去:在加下一条之前先把权值在这一条到下一条的之间的那些边都连上.连的时候要 ...

  8. NOI.AC #31 MST —— Kruskal+点集DP

    题目:http://noi.ac/problem/31 好题啊! 题意很明白,对于有关最小生成树(MST)的题,一般是要模拟 Kruskal 过程了: 模拟 Kruskal,也就是把给出的 n-1 条 ...

  9. P1906联合权值

    描述 无向连通图 G 有 n 个点,n-1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 WiWi, 每条边的长度均为 1.图上两点(u, v)的距离定义为 u 点到 v 点的最短距离. ...

随机推荐

  1. T100——作业单身网格消失,查询时单身无法输入

    增加代码:

  2. Fiddler之常用操作(过滤器设置,代理设置,手机抓包设置,手机代理配置)

    记录下,工作中常用的一些设置和操作~ 1.过滤“脏”请求 两个下拉框的名词解释: A.内外网过滤 No Zone Filter:不分区域过滤(内网外网都显示) Show only Intranet H ...

  3. 怎样理解DOM

    一句话总结: DOM 是一个 js 对象. 他可以赋予 js 控制 html 文档的能力.  全称: Document Object Model. DOM 的最小组成单位是: 节点 , 节点有7种类型 ...

  4. C#面向对象20 序列化和反序列化

    序列化和反序列化 序列化是把一个内存中的对象的信息转化成一个可以持久化保存的形式,以便于保存或传输,序列化的主要作用是不同平台之间进行通信,常用的有序列化有json.xml.文件等   一.序列化为j ...

  5. dev gridview拖拽数据移动

    设置属性gridView1.OptionsSelection.EnableAppearanceFocusedCell = false; //确保选定行的背景色一样. private BindingLi ...

  6. vue打开到新页面,并传递参数

    打开新页面,有两种方式, 一种是标签式: <router-link tag="a" target="_blank" :to="{path: '/ ...

  7. CSS3总结五:弹性盒子(flex)、弹性盒子布局

    弹性盒子容器的属性与应用 display:flex/inline-flex flex-direction flex-wrap justify-content align-items align-con ...

  8. 小程序setData方法使用总结

    做了一下小程序setData使用方法总结,如有错误,请不吝指出,Thanks♪(・ω・)ノ  //示例data: data:{ user:'young', obj:{ name:'蓝色蒲公英', ag ...

  9. 4 java 笔记

    1 javadoc工具默认只处理以public,protected修饰的类,接口,方法,成员变量,构造器和内部类之前的文档注释 2 文档注释以斜线后紧跟两个星号开始/**,以星号后紧跟一个斜线结束*/ ...

  10. 8.Hibernate性能优化

    性能优化 1.注意session.clear() 的运用,尤其在不断分页的时候 a) 在一个大集合中进行遍历,遍历msg,取出其中额含有敏感字样的对象 b) 另外一种形式的内存泄漏( //面试题:Ja ...