首页 > 其他分享 >2021 icpc 上海

2021 icpc 上海

时间:2024-10-28 13:35:06浏览次数:1  
标签:fa int sum 上海 tot icpc initEdge maxN 2021

H题 Life is a Game 题解
重构树 第一次听说 就是最小生成树但是每次加上一个虚拟的点 点的权重是两点相连的边权 然后从边权越大的点在更上面 所以如果我可以到达一个点我就一定可以到达他下面的所有点并且获得下面所有点的权重(经验) 怎么判断我从一个点出发能不能到达呢 我先预处理从每一个点出发到达他的所有祖先要的阈值是多少 然后拿题目给的k判断大于阈值就能到小于就不行
然后他的跳跃是二进制的跳跃 所以不会有太多层logn层

include

include

include

using namespace std;

const int maxN = 2e5 + 7;

struct Edge {
int from, to, dis;
}e[maxN], initEdge[maxN];

int n, m, q, head[maxN], cnt, tot, fa[maxN], f[maxN][23];
long long sum[maxN], maxNum[maxN][23], val[maxN];

inline void add(int u, int v, int w = 0)
{
e[++cnt].from = head[u];
e[cnt].to = v;
e[cnt].dis = w;
head[u] = cnt;
}

bool cmp(Edge x, Edge y)
{
return x.dis < y.dis;
}

int Find(int x)
{
return fa[x] == x? x : fa[x] = Find(fa[x]);
}

inline void KruskalTree() //Kruskal重构树
{
sort(initEdge + 1, initEdge + 1 + m, cmp);//先按边权排个序 小的在前
for(int i = 1; i <= n; ++i)//初始化
fa[i] = i;
tot = n;
for(int i = 1; i <= m; ++i) {
if(tot == (n << 1) - 1)
break;
int fx = Find(initEdge[i].from), fy = Find(initEdge[i].to);
if(fx == fy)
continue;
val[++tot] = initEdge[i].dis;
fa[tot] = fa[fx] = fa[fy] = tot;
add(tot, fx); add(tot, fy);
}
}

void dfs1(int x) //记录祖先,计算sum数组
{
if(x <= n) {
sum[x] = val[x];
return ;
}
for(int i = head[x]; i; i = e[i].from) {
int y = e[i].to;
f[y][0] = x;
dfs1(y);
sum[x] += sum[y];
}
}

void dfs2(int x) //更新maxNum (阈值)
{
maxNum[x][0] = val[f[x][0]] - sum[x];
for(int i = 1; i <= 19; ++i) {
f[x][i] = f[f[x][i - 1]][i - 1];
maxNum[x][i] = max(maxNum[x][i - 1], maxNum[f[x][i - 1]][i - 1]);
}
for(int i = head[x]; i; i = e[i].from) {
int y = e[i].to;
dfs2(y);
}
}

inline int query(int x, int k) //倍增求结果
{
for(int i = 19; i >= 0; --i)
if(f[x][i] && maxNum[x][i] <= k)//找到最大一个可以跳到的祖先然后再继续跳
x = f[x][i];
return sum[x];
}

int main()
{
scanf("%d%d%d", &n, &m, &q);
for(int i = 1; i <= n; ++i)
scanf("%lld", &val[i]);
for(int i = 1; i <= m; ++i)
scanf("%d%d%d", &initEdge[i].from, &initEdge[i].to, &initEdge[i].dis);//到的点
KruskalTree();
dfs1(tot); dfs2(tot); //注意,tot节点是新树的根节点
for(int i = 1; i <= q; ++i) {
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", y + query(x, y));
}
return 0;
}

标签:fa,int,sum,上海,tot,icpc,initEdge,maxN,2021
From: https://www.cnblogs.com/d-p-n-i-/p/18510339

相关文章

  • 【强化学习简明】台大李宏毅强化学习2021版课程笔记
    本文是基于台大李宏毅教授2021年的强化学习课程制作的课程笔记,旨在用通俗易懂的语言对强化学习进行介绍,搬运至bilibili的课程视频链接:视频链接https://www.bilibili.com/video/BV18r421j7S4/?spm_id_from=333.337.search-card.all.click&vd_source=22173a6fa342ecf648e799cd933......
  • [PA2021] Ranking sklepów internetowych
    算法显然可知,最大的权值显然是\(2\timesn+1\)我们也可以发现取最大值时序列的特征:中位数大于$\frac{n}{2}$,且包括整个大序列所有大于中位数的整数以及相等个数的小于中位数的数所以枚举中位数,找区间\([L,R]\)使得\(i\)到\(n\)的整数都在区间内,并且要求......
  • WPS 2021 下载及安装教程
    软件介绍WPS2021是一款功能强大的办公软件,由金山软件集团开发。它是一款跨平台软件,支持Windows、Mac和Linux操作系统。WPS2021不仅提供了功能齐全的文本编辑器,表格处理器和演示制作工具,还集成了PDF编辑器、笔记应用程序和邮件客户端功能。安装包下载WPS2021安装包免费......
  • P7912 [CSP-J 2021] 小熊的果篮 题解
    是模拟吗?其实是的,虽然$1\len\le2\times10^5$,但是队列是个好东西.我们定义一个结构体,来存放每一个块的信息,包括类型、起点、终点,将它们放入队列当中,再使用基于广搜的思想,先处理,再合并,所以需要用到$2$个队列.注意点数据中可能会有块的类型全是$1$,或者全是$0$的情况......
  • CVE-2021-27905(Apache Solr SSRF)漏洞复现
    CVE-2021-27905(ApacheSolrSSRF)ApacheSolr是一个开源的搜索服务,使用Java编写、运行在Servlet容器的一个独立的全文搜索服务器,是ApacheLucene项目的开源企业搜索平台。该漏洞是由于没有对输入的内容进行校验,攻击者可利用该漏洞在未授权的情况下,构造恶意数据执行SSRF攻击,......
  • 【上海普陀区】内向猫网络中大型手游项目招【cocos中高级程序员】15-20K
    一、你的日常1、玩转CocosCreator引擎,让你的手游客户端不仅会跑还能跳恰恰。编写那些让人看想玩的设计文档,然后用代码实现你的幽默感。2、你的代码就像段子手,质量高到让人捧腹,测试起来笑果十足。别忘了,优化代码就像减肥,得持续进行,让游戏跑得比兔子还快。3、开发或使用Cocos扩......
  • 适合数据库管理者的七个空间数据库(在2021版本中)
    适合数据库管理者的七个空间数据库(在2021版本中)最新推荐文章于 2024-09-0610:57:43 发布fmechina于2022-01-1116:43:00发布阅读量8.6k收藏23点赞数3分类专栏:默认分类文章标签:数据库postgresqldatabase  默认分类专栏收......
  • P7909 [CSP-J 2021] 分糖果
    结论题题面概括请在$[l,r]$中找出一个数$k$,使得$n$%$k$的值最大.思路当$n\le10^9$时,说明$\Theta(n)$的算法已经结束了.所以,接下来是结论推理.当$\left\lfloor\frac{l}{n}\right\rfloor=\left\lfloor\frac{r}{n}\right\rfloor$时,$r$%$n$的......
  • P7910 [CSP-J 2021] 插入排序 题解
    正解首先要注意$2$点:修改数组元素的值会影响接下来的操作.对数组进行排序不会影响接下来的操作.思路直接扫一遍数组.假设排序后$a_x$会在第$p$位上.将$p$初始化为$n$.然后就开始找$x$前后有多少个小于$a_x$的值就行了.时间复杂度:$\Theta(nq)$.注意......
  • P7911 [CSP-J 2021] 网络连接 题解
    模拟代码#include<iostream>#include<cstdio>#include<cstring>usingnamespacestd;intn,p=1,ans[1003];//没事干的ans数组structnode{ stringop,ad;}a[1003];intws(intn){//位数 intsum=0; if(n==0)return1; while(n){ n......