2021牛客暑期多校训练营2 L-WeChat Walk(分块)

L-WeChat Walk

在这里插入图片描述

在这里插入图片描述

每个大点记录一下邻接点的最大步数

每次修改的时候,枚举修改点的邻接的大点来更新

修改大点的时候直接判是不是比邻接点都大


代码抄的std好不容易才看懂~

Code1

#include<bits/stdc++.h>
using namespace std;
template <class T=int> T rd()
{T res=0;char ch=getchar();while(!isdigit(ch)) ch=getchar();while( isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();return res;
}
const int N=200010;
vector<int> d[N],g[N]; // d原图 g大点
int n,m,q,Bs;
int id[N],cnt;
int a[N];
int chmp[N],mx[N];
int h[550][20010];
int ne[N<<4],e[N<<4],idx;
int ans[N];
void add(int u)
{for(int v:g[u]){int s=id[v];e[idx]=u,ne[idx]=h[s][a[u]],h[s][a[u]]=idx++;;}
}
int main()
{n=rd(),m=rd(),q=rd();Bs=2*sqrt(m)+1;memset(h,-1,sizeof h);for(int i=1;i<=m;i++){int u=rd(),v=rd();d[u].push_back(v);d[v].push_back(u);}// 一个点周围的大点for(int i=1;i<=n;i++) for(int v:d[i]) if(d[v].size()>=Bs) g[i].push_back(v);for(int i=1;i<=n;i++) if(d[i].size()>=Bs) id[i]=++cnt;// 大点编号for(int i=1;i<=q;i++){int u=rd(),w=rd(); a[u]+=w;if(chmp[u]) {add(u);for(int v:g[u]) mx[v]=max(mx[v],a[u]);continue;}if(!id[u])// 由于a的增加使得周围某些点冠军状态被破坏 {while(1){int k=0,num=0;for(int v:d[u]){num=max(num,a[v]);if(chmp[v]&&(k==0||a[v]<a[k])) k=v;// 找到步数最小的冠军}if(!k)// 周围已经没有冠军 {if(num<a[u]) chmp[u]=i,add(u); // 看看自己是不是冠军break;}if(a[k]>a[u]) break;// 如果步数最小的冠军大于a[u]那么已经不会打破周围点的冠军状态ans[k]+=i-chmp[k];chmp[k]=0;// 更新周围点的冠军状态 累计答案}}else{int s=id[u];for(int t=a[u]-w+1;t<=a[u];t++) // a[u]+1~a[u]+w{for(int j=h[s][t];j!=-1;j=ne[j]){int v=e[j];if(a[v]==t&&chmp[v]) ans[v]+=i-chmp[v],chmp[v]=0;}}if(mx[u]<a[u]) chmp[u]=i,add(u);}for(int v:g[u]) mx[v]=max(mx[v],a[u]);}for(int i=1;i<=n;i++) if(chmp[i]) ans[i]+=q-chmp[i];for(int i=1;i<=n;i++) printf("%d\n",ans[i]);return 0;
}

Code2

KeHe大佬题解配合jiangly giegie的代码
考虑按步数 www 从大到小枚举

fuf_ufu表示 uuu 最近一次更新步数的时刻, lastu\text{last}_ulastu表示 uuu 上一次更新步数的时刻,初值均为最终时刻qqq

uuu 为小点直接暴力算周围的点。

uuu 为大点,考虑直接维护这个结果(记为 mnv\text{mn}_vmnv)即每个点步数更新时,枚举其周围所有大点 vvv 来更新 mnv\text{mn}_vmnv,由于每个点周围的大点的个数不超过mBs\frac{m}{\text{Bs}}Bsm,复杂度可行

#include<bits/stdc++.h>
using namespace std;
template <class T=int> T rd()
{T res=0;char ch=getchar();while(!isdigit(ch)) ch=getchar();while( isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();return res;
}
const int N=200010;
int n,m,q,Bs;
vector<int> e[N],big[N];
int walk[N],mx[N];
int ans[N];
vector<pair<int,int>> event[10005];
int main()
{n=rd(),m=rd(),q=rd();Bs=2*sqrt(m)+1;for(int i=1;i<=m;i++){int u=rd(),v=rd();e[u].push_back(v);e[v].push_back(u);}for(int i=1;i<=n;i++) for(int v:e[i]) if(e[v].size()>=Bs) big[i].push_back(v);for(int i=1;i<=q;i++){int u=rd(),w=rd();walk[u]+=w;event[walk[u]].push_back({u,i});}vector<int> f(n+1,q),last(n+1,q),mn(n,q);for(int w=10000;w>=1;w--){for(auto [u,t]:event[w]) {for(auto v:big[u])mn[v]=min(mn[v],t);last[u]=f[u],f[u]=t;}for(auto [u,t]:event[w]){if(e[u].size()<Bs){int r=last[u];for(auto v:e[u]) r=min(r,f[v]);ans[u]+=max(0,r-t);}else{ans[u]+=max(0,min(last[u],mn[u])-t);}}}for(int i=1;i<=n;i++) printf("%d\n",ans[i]);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318845.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客题霸 [求平方根] C++题解/答案

牛客题霸 [求平方根] C题解/答案 题目描述 实现函数 int sqrt(int x). 计算并返回x的平方根 题解&#xff1a; 要求返回平方根&#xff0c;我们就找一个i&#xff0c;使得ii<x&&(i1)(i1)>x 这样的i就是我们要找的答案 注意&#xff0c;x有可能为负数&#xf…

二分算法:平均值(洛谷 UVA1451)

解析 这道题寻找平均值的max&#xff0c;答案明显具有单调性&#xff0c;所以采用二分算法 从0到1不断取中点mid作为平均值的可能点&#xff0c;看是否存在不短于l的数列均值&#xff1e;mid不难得到以下代码&#xff1a; double st0,ed1;for(int i1;i<10;i){double mid(s…

P5287-[HNOI2019]JOJO【KMP】

正题 题目链接:https://www.luogu.com.cn/problem/P5287 题目大意 开始一个空串&#xff0c;nnn个操作 在末尾加入xxx个ccc字符&#xff08;保证和ccc和前面的字符不同&#xff09;返回到第xxx次操作之后 每次操作完成后求所有前缀的最长的borderborderborder长度和 1≤n≤…

牛客题霸 [数组中只出现一次的数字] C++题解/答案

牛客题霸 [数组中只出现一次的数字] C题解/答案 题目描述 一个整型数组里除了两个数字之外&#xff0c;其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 题解&#xff1a; 用map来记录每个数字出现几次&#xff0c;然后再循环一遍看哪个数字出现一次&#x…

Asp.NetCore依赖注入和管道方式的异常处理及日志记录

前言在业务系统&#xff0c;异常处理是所有开发人员必须面对的问题&#xff0c;在一定程度上&#xff0c;异常处理的能力反映出开发者对业务的驾驭水平&#xff1b;本章将着重介绍如何在 WebApi 程序中对异常进行捕获&#xff0c;然后利用 Nlog 组件进行记录&#xff1b;同时&a…

2021“MINIEYE杯”中国大学生算法设计超级联赛(2)I love counting(Trie树)

I love counting O{Mlog⁡aMAX(BN/B)}O\{M\log{a_{\text{MAX}}}(\text{BN/B})\}O{MlogaMAX​(BN/B)} md考场写的莫队Trie一直T #include<bits/stdc.h> using namespace std; using lllong long; using piipair<int,int>; using plipair<ll,int>; constexpr …

字符串:凯撒密码(洛谷P1914)

解析 只需将每一位ascll码加n即可 但要注意的是c的ascll码是有上限的 我一开始是这么写的&#xff1a; for(int i1;i<l;i){s[i] n;while(s[i]>z) s[i] - 26;printf("%c",s[i]);}结果&#xff1a; (真的是随便打的&#xff0c;不巧有些攻击性。。&#xff0…

P6113-[模板]一般图最大匹配【带花树】

正题 题目链接:https://www.luogu.com.cn/problem/P6113 题目大意 给出一张无向图&#xff0c;求最大匹配。 1≤n≤103,1≤m≤51041\leq n\leq 10^3,1\leq m\leq 5\times 10^41≤n≤103,1≤m≤5104 解题思路 带花树的模板&#xff0c;我也不会讲/kel 所以看下面两篇大佬的博…

牛客题霸 [跳台阶] C++题解/答案

牛客题霸 [跳台阶] C题解/答案 题目描述 一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法&#xff08;先后次序不同算不同的结果&#xff09;。 题解&#xff1a; 递归的入门题 如果只剩一个台阶&#xff0c;只有一种跳…

.NET Core实战项目之CMS 第四章 入门篇-Git的快速入门及实战演练

写在前面上篇文章.NET Core实战项目之CMS 第三章 入门篇-源码解析配置文件及依赖注入我带着大家通过分析了一遍ASP.NET Core的源码了解了它的启动过程&#xff0c;然后又带着大家熟悉了一遍配置文件的加载方式&#xff0c;最后引出了依赖注入以及控制反转的概念&#xff01;如果…

高精度:麦森数*(洛谷P1045)

P1045 [NOIP2003 普及组] 麦森数 解析 看似只是正常的一个高精 然而 暗藏杀机 一开始随手那么一写 。。。 (即使用了快速幂)时间复杂度过于感人 后来我们发现&#xff1a; 第一问位数的计算不必真的算出来&#xff0c;只需把2的p次幂转化为10的k次幂即可&#xff08;具体请…

2021“MINIEYE杯”中国大学生算法设计超级联赛(2)I love exam(背包)

I love exam 不知道为啥刚开始不写&#xff0c;那么简单的背包预处理dp&#xff0c;太菜了吧 fi,jf_{i,j}fi,j​对于第i门课来说花费j天得到的最大分数 gi,j,pg_{i,j,p}gi,j,p​考虑前i门课&#xff0c;花费j天复习得到的最大分数 #include<bits/stdc.h> using namespa…

P2012-拯救世界2【EGF】

正题 题目链接:https://www.luogu.com.cn/problem/P2012 题目大意 121212种东西排列成长度为nnn的序列&#xff0c;要求前四种出现奇数次&#xff0c;后四种出现偶数次&#xff0c;求方案。TTT组数据&#xff0c;对10910^9109取模。 1≤n<263,1≤T≤21051\leq n< 2^{63}…

彼之蜜糖,吾之砒霜——聊聊软件开发中的最佳实践

“描述一个事物&#xff0c;唯有一个名词定义它的概念&#xff0c;唯有一个动词揭露它的行为&#xff0c;唯有一个形容词表现它的特征。要做的&#xff0c;就是用心去寻找那个名词、那个动词、那个形容词……”—— 福楼拜 (Gustave Flaubert)我想讲个故事。很久很久以前&#…

贪心: Array Splitting(数列分段)(洛谷CF1175D)

解析 这题可以转化一下&#xff1a; &#xff08;《神笔马良》。。。。&#xff09; 计算这些长方形对应下标的总加和 我们可以一层一层往上垒,假设第i层起始点为xi&#xff0c;总和为sumi&#xff0c;再设从1到i的前缀和为si 显然第一层x11&#xff0c;sum1sn 对于第二层x2&…

牛客题霸 [合并有序链表] C++题解/答案

牛客题霸 [合并有序链表] C题解/答案 题目描述 将两个有序的链表合并为一个新链表&#xff0c;要求新的链表是通过拼接两个链表的节点来生成的。 题解&#xff1a; 首先判断l1和l2是否为空 然后依次比较l1和l2的值&#xff0c;然后存到新的链表里&#xff0c;当有一方全部结…

2021牛客暑期多校训练营2 G.League of Legends(转化+单调队列)

G.League of Legends Zechariah_2001题解 对于可以包含其他区间的大区间&#xff0c;要使得答案最优无非就是两种分组方式&#xff1a;单独一组或者与被包含的区间一组。单独一组那么贡献就是区间长度&#xff1b;如果说与被包含的区间一组&#xff0c;对答案贡献为0&#xff…

P5056-[模板]插头dp

正题 题目链接:https://www.luogu.com.cn/problem/P5056 题目大意 n∗mn*mn∗m的网格&#xff0c;求有多少条回路可以铺满整个棋盘。 解题思路 插头dpdpdp的&#xff0c;写法是按照题解上的写法。 状态用的是括号匹配&#xff0c;然后用了哈希邻接表&#xff08;挂表&#x…

牛客题霸 [用两个栈实现队列] C++题解/答案

题目描述 用两个栈来实现一个队列&#xff0c;完成队列的Push和Pop操作。 队列中的元素为int类型。 题解&#xff1a; 我们都知道栈的性质是先进后出&#xff0c;队列是先进先出 我们用两个栈来模拟出队列 可以先用一个栈来存数&#xff0c;当要输出时&#xff0c;最上面的是…

Docker最全教程——从理论到实战(一)

容器是应用走向云端之后必然的发展趋势&#xff0c;因此笔者非常乐于和大家分享我们这段时间对容器的理解、心得和实践。本篇教程持续编写了2个星期左右&#xff0c;只是为了大家更好地了解、理解和消化这个技术&#xff0c;能够搭上这波车。你可以关注我们的公众号“magiccode…