HNOI2010 总结

3175【HNOI2010】弹飞绵羊

L C T LCT LCT,维护链长度即可, L i n k ( i − > t o [ i ] ) Link(i->to[i]) Link(i>to[i]),出界的点 L i n k ( i − > s ) Link(i->s) Link(i>s),询问即求 i − > s i->s i>s链长

3196【HNOI2010】取石头游戏

贪心

首先简化问题:求出先手与后手差值的最大值(即先手加,后手减)

然后进一步简化

  • 对于 a i − 1 ≤ a i ≥ a i + 1 a_{i-1}\leq a_i\geq a_{i+1} ai1aiai+1,一定是当前先手取左右,当前后手取中间,所以直接缩成一个值 a i + 1 + a i − 1 − a i a_{i+1}+a_{i-1}-a_i ai+1+ai1ai

然后就变成了这个样子:
在这里插入图片描述

用红线分成两个部分

对于中间的若干个 V V V字形,可以发现两个蓝色箭头所指的两段可以合起来变成一个 V V V字形,所以中间的部分等价于一堆 V V V字形

然后对于这些 V V V字形,直接贪心取能取到的最大值,具体实现就是把每个左右端点丢到大根堆里面,取一个点出来就把它旁边的点丢进去

再考虑绿箭头部分(左右分别考虑)

  • 若有偶数个点,那么先手一定亏。

    先手取一个,后手马上取上面那个。这样后手每次都比先手大

  • 若有奇数个点,可以在红线的分界处分一个点到蓝箭头去(比如说 1 , 2 , 1 1,2,1 1,2,1可以分成 ( 1 ) ( 2 , 1 ) (1)(2,1) (1)(2,1),也可以分成 ( 1 , 2 ) ( 1 ) (1,2)(1) (1,2)(1)

  • 然后先取红箭头部分,取完后该谁先手就谁先手

3197【HNOI2010】城市建设

暴力线段树分治+LCT

由于常数问题,这个显然的做法行不通,考虑其它做法

C D Q CDQ CDQ分治+ k r u s k a l kruskal kruskal

考虑分治操作序列,假设当前为 ( l , r ) (l,r) (l,r)

  • 把当前区间被修改的边的边权变为 − ∞ -\infin

    再跑 k r u s k a l kruskal kruskal

    那么所有被选中的(非当前区间)的边都是必选边

    直接加贡献,然后把用必选边连起来的连通块缩成一个点,且不再考虑这些必选边

  • 把当前区间被修改的边的边权变为 ∞ \infin

    再跑 k r u s k a l kruskal kruskal

    那么所有没被选中的(非当前区间)的边都是必不选边

    直接扔掉不考虑

然后分治到 ( l , l ) (l,l) (l,l)时,跑最小生成树,并加上必选边的贡献即可

代码实现可以对 C D Q CDQ CDQ的每一层都开一个边集

3218【HNOI2010】合唱队

考虑当前队列 ( l , r ) (l,r) (l,r),加入一个人只会变成 ( l − 1 , r ) (l-1,r) (l1,r) ( l , r + 1 ) (l,r+1) (l,r+1),即只会扩张左边界或者右边界

考虑区间 d p dp dp,设 f [ i ] [ j ] [ 0 / 1 ] f[i][j][0/1] f[i][j][0/1]表示 ( i , j ) (i,j) (i,j)队列最后一个进来的是左( 0 0 0)还是右( 1 1 1)

  • f [ i ] [ j ] [ 0 ] + = f [ i + 1 ] [ j ] [ 0 ] ( a [ i ] < a [ i + 1 ] ) f[i][j][0]+=f[i+1][j][0](a[i]<a[i+1]) f[i][j][0]+=f[i+1][j][0]a[i]<a[i+1]
  • f [ i ] [ j ] [ 0 ] + = f [ i + 1 ] [ j ] [ 1 ] f[i][j][0]+=f[i+1][j][1] f[i][j][0]+=f[i+1][j][1] a [ i ] < a [ j ] a[i]<a[j] a[i]<a[j]
  • f [ i ] [ j ] [ 1 ] + = f [ i ] [ j − 1 ] [ 0 ] f[i][j][1]+=f[i][j-1][0] f[i][j][1]+=f[i][j1][0] a [ j ] > a [ i ] a[j]>a[i] a[j]>a[i]
  • f [ i ] [ j ] [ 1 ] + = f [ i ] [ j − 1 ] [ 1 ] f[i][j][1]+=f[i][j-1][1] f[i][j][1]+=f[i][j1][1] a [ j ] > a [ j − 1 ] a[j]>a[j-1] a[j]>a[j1]

初始化

  • f [ i ] [ i ] [ 0 ] = 1 f[i][i][0]=1 f[i][i][0]=1
  • 注意到如果 f [ i ] [ i ] [ 1 ] f[i][i][1] f[i][i][1]也等于 1 1 1,则会出现重复计算,所以只初始化一个

3219【HNOI2010】平面图判定

图大概长这个样子:
在这里插入图片描述
容易发现一条边只有两种选择:

  • 环内
  • 环外

然后对于相交,可以看成是两条边在同一侧
在这里插入图片描述
同时注意到一条边只可能是内外中的一个

就想到了 2 − S A T 2-SAT 2SAT问题

对于相交的两条边 u , v u,v u,v

  • u 1 u_1 u1-> v 2 v_2 v2
  • u 2 u_2 u2-> v 1 v_1 v1
  • v 1 v_1 v1-> u 2 u_2 u2
  • v 2 v_2 v2-> u 1 u_1 u1

所以相当于连了 ( u 1 , v 2 ) ( u 2 , v 1 ) (u_1,v_2)(u_2,v_1) (u1,v2)(u2,v1)两条双向边

所以原来用 T a r j a n Tarjan Tarjan跑连通,现在可以直接并查集维护(代码短了很多)

最后判一下 u 1 u_1 u1 u 2 u_2 u2是否在一个集合即可

3220【HNOI2010】物品调度

Case 1 确定位置

对于每一个 i i i,假设 y i y_i yi确定,那么对应的位置分别是 c i + y i , c i + y i + d ⋯ c i + y i + k ⋅ d c_i+y_i,c_i+y_i+d\cdots c_i+y_i+k\cdot d ci+yi,ci+yi+dci+yi+kd

可以看成是一个间隔为 d d d的环

考虑暴力,从小到大枚举 y y y,再从小到大枚举 x x x,相当于依次枚举每个环,然后再枚举环上的每个位置

对于暴力的优化,可以使用两个并查集

一个用来维护每个环上的位置,且 f a [ x ] fa[x] fa[x]表示这个环上 x x x后面第一个空,每次用完一个位置,就令 f a [ x ] = ( x + d ) % n fa[x]=(x+d)\%n fa[x]=(x+d)%n即可

类似的,第二个用来维护每个环, f a [ y ] fa[y] fa[y]表示 y y y这个环后面第一个有空的环

同时记录 v i s vis vis数组方便查看这个位置是否被用过,注意到 v i s [ X . F i n d ( y ) ] = = t r u e vis[X.Find(y)]==true vis[X.Find(y)]==true即表示 y y y这个环上没有空了

Case 2 求答案

遍历每个环

  • 包含空位( s s s)的,贡献为 l e n − 1 len-1 len1
  • 否则贡献为 l e n + 1 len+1 len+1
  • 同时长度为 1 1 1的,贡献为 0 0 0(不用动)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用\[1\]和引用\[2\]的描述,题目中的影魔拥有n个灵魂,每个灵魂有一个战斗力ki。对于任意一对灵魂对i,j (i<j),如果不存在ks (i<s<j)大于ki或者kj,则会为影魔提供p1的攻击力。另一种情况是,如果存在一个位置k,满足ki<c<kj或者kj<c<ki,则会为影魔提供p2的攻击力。其他情况下的灵魂对不会为影魔提供攻击力。 根据引用\[3\]的描述,我们可以从左到右进行枚举。对于情况1,当扫到r\[i\]时,更新l\[i\]的贡献。对于情况2.1,当扫到l\[i\]时,更新区间\[i+1,r\[i\]-1\]的贡献。对于情况2.2,当扫到r\[i\]时,更新区间\[l\[i\]+1,i-1\]的贡献。 因此,对于给定的区间\[l,r\],我们可以根据上述方法计算出区间内所有下标二元组i,j (l<=i<j<=r)的贡献之和。 #### 引用[.reference_title] - *1* *3* [P3722 [AH2017/HNOI2017]影魔(树状数组)](https://blog.csdn.net/li_wen_zhuo/article/details/115446022)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [洛谷3722 AH2017/HNOI2017 影魔 线段树 单调栈](https://blog.csdn.net/forever_shi/article/details/119649910)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值