[TJOI2013]拯救小矮人(反悔贪心证明),「ICPC World Finals 2019」Hobson 的火车(基环树,差分)

2021-09-07 test

  • [TJOI2013]拯救小矮人
  • 「ICPC World Finals 2019」Hobson 的火车

[TJOI2013]拯救小矮人

luogu4823

考试题目的数据加强为2e5,所以此题做法应为O(nlog⁡n)O(n\log n)O(nlogn)反悔贪心

这种有多元属性,选择最优的问题

如果发现简单的贪心总是半错半对的

解法通常有两种

  • 设计dp进行转移
  • 考虑反悔贪心

此题也不意外

定义每个人所需的逃出高度为H−ai−biH-a_i-b_iHaibi

observation1 : 逃出高度越高的人越先逃出

当然可能某些人的属性是极端的,比如身高非常高而手很短,却被派到前面,这个时候可能不让此人逃走能让后面的人走得更多,才是最佳方案

从这种情况上得出

observation2 : 如果断定此人不逃出,那么就永远不会再给机会逃出

observation3 : 如果此人不能逃出,但是前面逃出的人有高度更高的,就把最高的那个人扔回来,换成这个人逃出

到这里就可以使用优先队列维护做了

接下来给出性质一和性质三的证明

  • 性质一:

    考虑先逃走的人逃出高度为h1h_1h1,再逃走的逃出高度为h2h_2h2

    则有h1>h2h_1>h_2h1>h2,即H−a1−b1>H−a2−b2⇒a1+b1<a2+b2H-a_1-b_1>H-a_2-b_2\Rightarrow a_1+b_1<a_2+b_2Ha1b1>Ha2b2a1+b1<a2+b2

    hhh为还在洞内所有人的身高包含1,2

    如果1,2都能逃出,那么1,2之间逃出的顺序,对后面的人不会影响,反正都不会有身高的贡献

    也就是说,我们需要证明当满足h1>h2h_1>h_2h1>h2条件时,1更难逃出,所以需要先走

    既然2能逃走,说明不需要1的身高,即h−a1+a2+b2≥Hh-a_1+a_2+b_2\ge Hha1+a2+b2H

    如果2先逃走,1也能逃走,则必须满足h−a2+a1+b1≥Hh-a_2+a_1+b_1\ge Hha2+a1+b1H

    • −a1+a2+b2?−a2+a1+b1⇔a2+a2+b2?a1+a1+b1-a_1+a_2+b_2\quad?\quad -a_2+a_1+b_1\Leftrightarrow a_2+a_2+b_2\quad ?\quad a_1+a_1+b_1a1+a2+b2?a2+a1+b1a2+a2+b2?a1+a1+b1

      a1+b1<a2+b2⇒a1<a2+b2−b1a_1+b_1<a_2+b_2\Rightarrow a_1<a_2+b_2-b_1a1+b1<a2+b2a1<a2+b2b1

      a1+a1+b1<a2+b2−b1+a1+b1=a2+b2+a1a_1+a_1+b_1<a_2+b_2-b_1+a_1+b_1=a_2+b_2+a_1a1+a1+b1<a2+b2b1+a1+b1=a2+b2+a1

    所以?应为>

    也就是说2逃出时超出HHH的距离更多,也就是比1逃出条件要松一点

    如果1逃走后2无法出逃,那么2逃走后1更无法逃出,且加紧了后面的约束

    当然这只是充分证明,因为会考虑逃不走换人的情况,结合反悔贪心才是最后的贪心

  • 性质三:

    对于某个不能逃出的人,选择前面比自己高的最高的人,换进来

    这反悔贪心很显然,换一个人进来换一个人出去,对人数没有影响

    但是换了个更高的人进来,那么其高度就会松弛后面所有人的逃出条件,使得逃出可能性增大

    • 接下来证明,在逃出条件越后越松弛的前提下,换一个更高的人进来,自己一定可以逃出去

      假设2此时无法逃出,需要把前面的1换进来,定义hhh为在洞内的人的高度加上已经逃出的1的高度

      a1+b1<a2+b2a_1+b_1<a_2+b_2a1+b1<a2+b2a1>a2a_1>a_2a1>a2

      把在1,2之间逃出洞的所有人先再次丢回洞中,相当于回溯到第一次决定让1逃出的时刻

      因为逃出高度限制是逐渐宽松的,既然这个时候1能逃出,2一定也能逃出

      考虑变成2逃出对之前在1,2中间逃出的人的影响,发现是正面影响

      因为2的高度没有1高,相当于换了一个更高的人垫背,那么原来在1,2中间逃出的人同样也会逃离

#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long 
#define maxn 200005
priority_queue < int > q;
struct node { int a, b, h; }p[maxn];
int n, H;
int h[maxn];signed main() {scanf( "%lld", &n );for( int i = 1;i <= n;i ++ )scanf( "%lld %lld", &p[i].a, &p[i].b );scanf( "%lld", &H );for( int i = n;i;i -- )p[i].h = H - p[i].a - p[i].b;sort( p + 1, p + n + 1, []( node x, node y ) { return x.h > y.h; } );for( int i = n;i;i -- )h[i] = h[i + 1] + p[i].a;int now = 0, ans = 0;for( int i = 1;i <= n;i ++ )	if( now + h[i + 1] >= p[i].h ) ans ++, q.push( p[i].a );else {if( ! q.empty() and q.top() > p[i].a )now += q.top(), q.pop(), q.push( p[i].a );elsenow += p[i].a;}printf( "%lld\n", ans );return 0;
}

「ICPC World Finals 2019」Hobson 的火车

LOJ6548

恰好考了一下最近学的基环树

如果是问从每个点开始能访问的点数,那么就非常简单,是个外环树

每个非环树上的点的路径都是一条链,只需要考虑深度和kkk的关系即可

但不巧的是这道题是求每个点可以被多少个点访问到,是个内环树

发现时间卡在设计DPDPDPkkk转移上

很妙的,又是前几天考试的解法就是——树上差分和环上差分

具体细节实现可看代码及注释

#include <cstdio>
#include <vector>
using namespace std;
#define maxn 500005
vector < int > G[maxn], circle;
int n, k, siz, top;
int ans[maxn], dep[maxn], vis[maxn], s[maxn], d[maxn];void dfs( int u, int rt ) {if( ! vis[u] ) vis[u] = 1; //在求该联通分量时可能有些点还未访问过 身处环遍历后面 s[++ top] = u;if( top > k + 1 and s[top - k - 1] ^ circle[rt] )	//差分 与u点相距k+1甚至更远的点不再有贡献 ans[s[top - k - 1]] --;for( auto v : G[u] )if( vis[v] == 2 ) continue;//环点在后面单独更新else { dep[v] = dep[u] + 1;dfs( v, rt );if( u ^ circle[rt] ) ans[u] += ans[v];}top --;if( dep[u] <= k ) { //会延伸到部分环点 哪怕只有一个点 //环长虽然是siz 但实际上只需要走siz-1步就会遍历完所有环点 if( dep[u] + siz > k + 1 ) { //无法在k步内将环都覆盖完 int t = ( rt + k - dep[u] + 1 ) % siz;/*rt+k-dep[u]是真正差分的结束位置需要在结束位置的下一位pos+1打上-1抵消标记 */ans[circle[rt]] ++, ans[circle[t]] --;if( t < rt ) ans[circle[0]] ++;/*由于环差分也是从环头遍历到环尾 默认断开了环头与环尾的边 该if成立说明覆盖的部分点跨越了环尾在环头多延伸了一点 环头到结束位置也应该差分*/ }else ++ ans[circle[0]]; //该点可以访问所有环点 直接在环头++ }if( u ^ circle[rt] ) ans[u] ++; 
}void dfs( int now ) {circle.clear();while( vis[now] ^ 2 ) { //如果now点先前已经被遍历2次 也就是回到了环头 不再重复入环 if( vis[now] ) circle.push_back( now ); //再次经过now点说明是环上一点 开始进入求环部分 vis[now] ++;now = d[now];}siz = circle.size();for( int i = 0;i < siz;i ++ )//先差分求每个环点的非环树答案 dfs( circle[i], i );for( int i = 1;i < siz;i ++ )//环差分 ans[circle[i]] += ans[circle[i - 1]];
}int main() {scanf( "%d %d", &n, &k );for( int i = 1;i <= n;i ++ ) {scanf( "%d", &d[i] );G[d[i]].push_back( i );//建反图 }for( int i = 1;i <= n;i ++ )if( ! vis[i] ) dfs( i );for( int i = 1;i <= n;i ++ )printf( "%d\n", ans[i] );return 0;
}

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

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

相关文章

Dotnet全平台下APM-Trace探索

随着支撑的内部业务系统越来越多&#xff0c;向着服务化架构进化&#xff0c;在整个迭代过程中&#xff0c;会逐渐暴露出以下问题。传统依赖于应用服务器日志等手段的排除故障原因的复杂度越来越高&#xff0c;传统的监控服务已经无法满足需求。终端--> Nginx --> IIS --…

生成函数全家桶

文章目录有用的式子1.&#xff08;牛顿二项式定理&#xff09;2.普通生成函数&#xff08;OGF&#xff09;常见封闭形式&#xff1a;1.2.3.4.指数生成函数&#xff08;EGF&#xff09;排列与圆排列有用的式子 1.&#xff08;牛顿二项式定理&#xff09; 我们把组合数的定义推…

2020年牛客多校第五场C题-easy(纯组合计数不要生成函数的做法)

文章目录descriptionsolutioncodedescription 有TTT组测试数据 对于两个长度为KKK的数列{a}\{a\}{a}和{b}\{b\}{b}&#xff0c;满足∑i1KaiN,∑i1KbiM\sum_{i1}^Ka_iN,\sum_{i1}^Kb_iM∑i1K​ai​N,∑i1K​bi​M 对于这两个数列&#xff0c;定义权值为P∏i1Kmin⁡(ai,bi)P\p…

部署Chart应用并使用.net core读取Kubernetes中的configMap

上一篇文章讲了 k8s使用helm打包chart并上传到腾讯云TencentHub&#xff0c;今天就讲一下使用Helm部署应用并使用configMap代替asp.net core 中的appsettings.json文件。把Chart上传到TencentHub之后&#xff0c;我们就可以通过腾讯云的容器服务&#xff0c;直接部署Helm应用了…

Vases and Flowers HDU - 4614

Vases and Flowers HDU - 4614 题意: 一排空瓶子放花&#xff0c;操作1&#xff1a;从第x个瓶子开始放花&#xff0c;放y朵花&#xff0c;每个瓶子就一朵花&#xff0c;如果碰到已经有花的瓶子跳过这个瓶子&#xff0c;看下一个&#xff0c;当花没了&#xff0c;或者瓶子不够…

洛谷P3327:[SDOI2015]约数个数和(莫比乌斯反演)

枚举倍数的一种灵活的变形&#xff1a;g(d)∑d∣inf(i)∑i1⌊nd⌋f(i⋅d)g(d)\sum_{d|i}^nf(i)\sum_{i1}^{\lfloor\frac{n}{d}\rfloor}f(i\cdot d)g(d)∑d∣in​f(i)∑i1⌊dn​⌋​f(i⋅d) 很显然&#xff0c;但有时能发挥大作用。 其实本质还是要理解西格玛究竟是在算什么 解析…

EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

前言α角 与 β角关于α角 与 β角的介绍&#xff0c;请见上文 如何用EFCore Lazy Loading实现Entity Split。本篇会继续有关于β角的彩蛋在等着大家去发掘。/斜眼笑其他本篇的程序&#xff0c;可以在 https://github.com/kentliu2007/EFCoreDemo/tree/master/InheritanceWithE…

专题突破之反悔贪心——建筑抢修,Cow Coupons G, Voting (Hard Version),Cardboard Box

文章目录[JSOI2007]建筑抢修[USACO12FEB]Cow Coupons GCF1251E2 Voting (Hard Version)CF436E Cardboard Box[JSOI2007]建筑抢修 luogu4053 将建筑按照结束时间从小到大排序 然后记录一下已经修理的建筑总共的花费时间 如果花费时间加上现在这个建筑的修建时间超过了这个建…

Max Sum Plus Plus HDU - 1024

Max Sum Plus Plus HDU - 1024 题意&#xff1a; 给你n个数&#xff0c;选m个子段&#xff0c;各个子段连续且不相交&#xff0c;长度可以为1&#xff0c;设maxn为各个子区间的和&#xff0c;求最大的maxn。 题解&#xff1a; 设dp[i][j]表示前j个数分成i段的最大值 对于第…

模板:杜教筛(莫比乌斯反演、数论)

所谓杜教筛&#xff0c;就是dms教给我们的筛 &#xff08;逃&#xff09; 前言 与其说算法&#xff0c;不如说是技巧。 可以在低于线性的时间复杂度&#xff08;准确的说是 O(n23)O(n^{\frac{2}{3}})O(n32​)&#xff09;内完成对积性函数的前缀和计算。 解析 考虑求函数 f…

程序员过关斩将--快速迁移10亿级数据

菜菜呀&#xff0c;咱们业务BJKJ有个表数据需要做迁移程序员主力 Y总现在有多少数据&#xff1f;菜菜大约21亿吧&#xff0c;2017年以前的数据没有业务意义了&#xff0c;给你半天时间把这个事搞定&#xff0c;绩效给你A程序员主力 Y总有绩效奖金吗&#xff1f;菜菜钱的事你去问…

[2021-09-09 T2] 就差⼀点——冒泡排序和反序表之间不为人知的秘密

就差一点解题报告descriptionsolutioncodedescription 题目描述 冒泡排序是⼀个简单的排序算法&#xff0c;其时间复杂度为O(n2)O(n^2)O(n2) 有⼀个大小为nnn的排列p1,...,pnp_1,...,p_np1​,...,pn​&#xff0c;⼩明想对这个排列进⾏冒泡排序&#xff0c;于是写了下⾯这份…

CodeForces - 76E Points

CodeForces - 76E Points 题意&#xff1a; 给你n个点的坐标&#xff0c;求所有一对点之间的距离的平方和 n<100000 题解&#xff1a; 直接暴力n2肯定不行&#xff0c;我们把这个的式子列出来&#xff1a; 代码&#xff1a; #include<bits/stdc.h> #define deb…

模板:Miller-RabinPollard-Rho(数论)

所谓 pollard-rho&#xff0c;就是泼辣的肉 &#xff08;逃&#xff09; 前言 许多题解都把这两个算法放在了一起。 那我也这样办吧&#xff01; miller-rabin可以在优秀的时间复杂度内完成对一个数的素性检测。 而pollard-rho则是立足于Miler-rabin之上&#xff0c;可以在 …

Asp.NetCore轻松学-部署到 Linux 进行托管

前言上一篇文章介绍了如何将开发好的 Asp.Net Core 应用程序部署到 IIS&#xff0c;且学习了进程内托管和进程外托管的区别&#xff1b;接下来就要说说应用 Asp.Net Core 的特性&#xff08;跨平台&#xff09;&#xff0c;将 .NetCore 部署到 Linux 中&#xff0c;主流的 Linu…

DevC++ 用C语言的多线程 实现简单的客户端和服务器

知识来源一&#xff1a; 使用Dev-C实现简单的客户端和服务器-CSDN博客 此先生的博客使用的是win32 SDK来创建多线程&#xff0c;然后鄙人对这个版本的多线程细节不明。于是又重新用C语言的线程替代win32API,以此继续学习服务器代码。 知识来源二&#xff1a;DevC 多线程创建…

[2021-09-09 T3] 序列/luogu P3943 星空(异或差分+bfs最短路+状压dp)

序列descriptionsolutioncodedescription 题目描述 长度为nnn的序列&#xff0c;初始全为000&#xff0c;每次可以选择⼀个数ai(1≤i≤l)a_i(1\le i\le l)ai​(1≤i≤l)&#xff0c;然后选择连续aia_iai​个元素异或上111 求最少的次数&#xff0c;使得对于所有i(1≤i≤k)i(…

HDU - 4608 I-number

题意&#xff1a; 给你一个x&#xff0c;让你构造一个y&#xff0c;y的要求&#xff1a; y>xy的各项之和为10的倍数在满足前两个的前提下&#xff0c;y尽可能小 题解&#xff1a; 模拟&#xff0c;尽可能的模拟&#xff0c;用字符串模拟 先将各位相加得到sum&#xff0c…

从初创公司的角度来看微服务

在开展微服务的过程中&#xff0c;了解要考虑哪些因素可能是非常有挑战性的事情。没有可以直接使用的金科玉律。每个过程都是不同的&#xff0c;因为每个组织面临的都是不同的环境。在本文中&#xff0c;我将从初创公司的角度分享我们学习到的经验和面临的挑战&#xff0c;以及…

洛谷P2056:[ZJOI2007]捉迷藏(点分树、STL)

解析 见到动态维护最远点对&#xff0c;不难想到利用 set 维护最大值和次大值&#xff0c;每个点维护两个 set 的杂技做法。 但是问题是…T了啊。 咋办嘞。 一个在本题至关重要的 trick&#xff1a;利用两个堆来支持访问最大值和删除 具体也很好理解&#xff1a;当删除的时候…