liaoliao的题表..

版权声明:神的bolg... https://blog.csdn.net/Rose_max/article/details/86497814

前言

不开别的博客水访问量了
开个合辑吧…
不标题号的都是bzoj

3441

可以知道每个水缸要做多少次变为0
然后你就可以每次找最小那个次数,然后计算在哪个水缸让他变为0了
在这中间所有能喝的水缸都是可以喝的
然后就可以把这个水缸去掉继续做上面那个过程
复杂度是 m l o g m mlogm

3681

感受一下就是个主席树优化建图
日常主席树上树之后
但是要让之前连的边不能走到合并后的另外节点上
所以你线段树合并的时候
把两个线段树都有的那个点换成新点,这个新点向这两个点连边
这样就可以保证之前连的边不会走到合并后的节点上
新点的数量就是线段树合并的复杂度,所以是 n l o g n nlogn
然后直接dinic就过了…

3956

感觉这题就是 H N O I 2017 HNOI2017 影魔的弟弟题…
虽然那题我并没有用这个做法做
可以发现,对于一个合法的好点对 ( i , j ) (i,j) ,他之间一定存在至少一个最大值 x x 满足 L [ x ] = i L[x]=i R [ x ] = j R[x]=j ,其中 L [ x ] , R [ x ] L[x],R[x] 分别表示左边,右边第一个比自己大的位置
并且一个能作为最大值的位置,只会贡献这一组不同的好点对
否则一定是另外的点作为内部最大值来贡献的…
然后就是要数 [ l , r ] [l,r] 内有多少个数满足 L [ x ] > = l L[x]>=l R [ x ] < = r R[x]<=r
有一些 L [ x ] , R [ x ] L[x],R[x] 一样重复的最大值,去掉就好了…
这个主席树在 R [ x ] R[x] 上插入 L [ x ] L[x] 做一下就好了吧…

1304

直接dp
设一个 f [ i ] [ 0 / 1 / 2 / 3 ] f[i][0/1/2/3] 表示当前节点染黑/染白并且下面合法,当前节点不染色并且下面需要放的都是黑/白
转移直接扔一段代码吧…

for(int i=0;i<=1;i++)
{
	if(i==0)f[x][i]+=min(min(f[y][0],f[y][1]),f[y][2]);
	else f[x][i]+=min(min(f[y][0],f[y][1]),f[y][3]);
}
for(int i=2;i<=3;i++)f[x][i]+=min(min(f[y][0],f[y][1]),f[y][i]);

二次扫描的时候也一样做就可以了…
注意不合法的状态直接设为 i n f inf ,没人会继承他…

2118

可以知道,每个能被组成的数都能被表示为 k a [ 1 ] + b k*a[1]+b 的形式
对于每个 b b ,我们只需要找到最小的 k k 使得 k a [ 1 ] + b k*a[1]+b 能被组成,因为接下来 ( k + 1 ) , ( k + 2 ) . . (k+1),(k+2).. 都可以被组成,并且一定与其他能组成的数不相同
所以就可以转化成图论来做
复杂度是 n m i n ( a [ i ] ) l o g ( n ) n*min(a[i])*log(n)
这种能被表示的一类题型还是要多想想图论啊…

2298

首先可以转化为找最多说真话的人
显然人的编号没用…然后就是要找一个合法的排名使得最多句话是真的
这样的排名一定是 = . . . = &lt; = . . . = &lt; &lt; . . = ... = &lt; = ... = &lt; &lt;.. 的,就是等于掺杂小于
设一个 f [ i ] f[i] 表示已经安排好了前 i i 个人的排名且满足从小到大的最多真话
暴力转移的话枚举最后一个小于号在哪里,设一个 A [ i ] [ j ] A[i][j] 表示排名为 j j ,并且上一个不同的排名是 i i 的人有多少个,就是 f [ i ] = m a x ( f [ j ] + m i n ( j i , A [ j ] [ i ] ) ) f[i]=max(f[j]+min(j-i,A[j][i]))
显然有贡献的 A [ j ] [ i ] A[j][i] 最多只有 1 0 5 10^5 个,转移的时候枚举有贡献的转移就可以了
其他取一个max,最后记得用n去减…

2299

有用的向量就那么四个…式子写出来就是这样
u 1 ( a , b ) + u 2 ( b , a ) + u 3 ( a , b ) + u 4 ( b , a ) = ( X , Y ) u1*(a,b)+u2*(b,a)+u3*(a,-b)+u4*(b,-a)=(X,Y)
拆一下就有
u 1 a + u 2 b + u 3 a + u 4 b = X u1*a+u2*b+u3*a+u4*b=X
u 1 b + u 2 a u 3 b u 4 a = Y u1*b+u2*a-u3*b-u4*a=Y
然后就是
( u 1 + u 3 ) a + ( u 2 + u 4 ) b = X (u1+u3)*a+(u2+u4)*b=X
( u 1 u 3 ) a + ( u 2 u 4 ) b = Y (u1-u3)*a+(u2-u4)*b=Y
裴蜀定理一下可以知道 g c d ( a , b ) X gcd(a,b)|X g c d ( a , b ) Y gcd(a,b)|Y
然而这样只能满足 u 1 + u 3 u1+u3 u 1 u 3 u1-u3 有整数解,并不代表分别有整数解
我们发现仅当这两个数奇偶性相同的时候才会有整数解
所以分四种情况讨论一下,就是
2 g c d ( a , b ) X , 2 g c d ( a , b ) ( X + b ) , 2 g c d ( a , b ) ( X + a ) , 2 g c d ( a , b ) ( X + a + b ) 2*gcd(a,b)|X,2*gcd(a,b)|(X+b),2*gcd(a,b)|(X+a),2*gcd(a,b)|(X+a+b)
对于 u 2 , u 4 u2,u4 Y Y 也是一样
所以上面四种情况只要满足一种就是成立的…注意爆 i n t int

3106

这题有点东西…
S G SG 函数看成曼哈顿距离的话显然当白子第一次不能吃掉黑子的时候白子就一定输了
最后状态一定是偶数
因为白子无论如何都会改变奇偶性,而黑子可以使他操作的时候奇偶性不变
然后有一个很naive的想法就是直接 f [ o p t ] [ x 1 ] [ y 1 ] [ x 2 ] [ y 2 ] f[opt][x1][y1][x2][y2] 表示谁操作,棋子分别在哪的最优解是什么…然后搜的时候就发现可以搜出环过不了…
然后其实最多步数不会超过 3 n 3n ,然后把步数压进状态里搜就可以避免环的情况了…
要知道这种把步数压进状态里的奇奇妙妙的想法

2306

开始想着用一个矩乘优化转移做那么几百万次…
然后发现要取max和整体加
然后就发现矩乘做不了…换成倍增floyd做
就是 d p [ i ] [ j ] = m a x ( g [ i ] [ k ] + p 2 z g [ k ] [ j ] ) dp[i][j]=max(g[i][k]+p^{2^z}*g[k][j])
暴力做他几百万次这个p的贡献就没了
大致思想就还是给后面一段整体乘上一个值使得能接上
注意这只蚂蚁可以在原地不动
注意要连一条边权为0的自环

2656

感受一下就发现直接分治的不同节点数不会很多
那就直接记忆化一下做了23333
收获了一个高精度板子很兹瓷
理性证明右转百度

2728

这题吼啊…
事实上是被OZYdiss的体无完肤
手玩一下就可以发现,这个NAND可以做所有位运算,比如非,与,或这些…
然后就是告诉你一些数,你可以做任何运算,求你能组成多少个不同的数
那么
如果第 i i 位和第 j j 为在所有数中都是一样的,要不就都出现要不都不出现
显然你怎么运算这两位都是一样的,变1就同时变1,变0就同时变0
所以你可以预处理一些位,表示这些位怎么做都是一样的
然后开始类似数位dp,扫的过程中只需要关注这位顶不顶格以及合不合法
不顶格的话显然后面怎么放集合都是ok的是一个 2 i 2^i ,顶格就继续做下去
注意每次把集合打上标号表示这个集合只能填0或者1了

2878

树的情况很好做,直接dp来做
可以预处理一个 f 1 [ i ] f1[i] 表示这个节点只走子树的期望,就是除 d e g [ i ] 1 deg[i]-1 ,和一个 f 2 [ i ] f2[i] 表示这个节点乱走的期望,就是除 d e g [ i ] deg[i]
二次扫描一下就做完了
环的情况的话
发现这个环最多就那么20个点,然后就可以考虑枚举环上每个点来做
然后你就把这个点从左往右走和从右往左走的期望搞出来
这个点的期望就是走环和走子树的期望的和
然后就扫下去没有环的子树,这个地方扫的时候和上面树的做法是一样的
大概环的点多点也是可以做的?

3712

我的做法比较奇怪…
把树直接建出来,显然只需要在这个点讨论LCA是自己的那些反应的顺序
可以开一个vector表示反应位置在父亲的反应是什么
然后你按照邻接表倒序加入,其实就是按照他给的反应时间顺序加入
这个点加入这个孩子的时候,扫他的vector,看看这个反应是不是可以进行了,相当于他需要的两个节点的子树都已经被加入了,可以的话就取个min进行一下…
感觉跟别人不太一样啊…

3997

这个题不会做.
开始YY了一个想法就是看每个点右下角有多少条必须走的路径,有的话你就拿一些来用
但是这样的话有个问题就是你不知道拿的是右边的贡献还是下面的贡献
然后传递给后面的时候就GG了
然后就凉凉了,其实是又被OZYdiss飞了
大概看了看Dilworth定理,就是DAG的最小链覆盖等于最大独立集
那么这张图的最大独立集,显然一个点不能到他严格右上方的点,一个点也不能到他严格左下方的点
然后你就可以 f [ i ] [ j ] f[i][j] 表示以 ( i , j ) (i,j) 为左下角的矩形的独立集是什么
转移就是 m a x ( f [ i 1 ] [ j ] , f [ i ] [ j + 1 ] , f [ i 1 ] [ j + 1 ] + a [ i ] [ j ] ) max(f[i-1][j],f[i][j+1],f[i-1][j+1]+a[i][j])
正确性是显然的
要记住这种DAG图的最小覆盖计数的问题啊…

4667

这个K就是来吓你的
哪天我出个K=200000的改成乘法让你取对数吓死你
把表打出来发现最多就那么9W个状态…
就是把数位从小到大排列后不同的状态就那么几万个
那就直接数位dp一下
不顶格的时候就最多那么100次,
暴力枚举剩下的数位状态是什么,然后暴力判合不合法
而且非常不满…所以跑的飞快

3810

开始想了个dp然后爆炸了
因为只考虑了上左边界没有考虑下边界和右边界的问题
其实这么小还可以记忆化搜一下
f [ x ] [ y ] [ o 1 ] [ o 2 ] [ o 3 ] [ o 4 ] f[x][y][o1][o2][o3][o4] 表示长宽,上下左右是不是边界
然后每次把这个矩形分成两份,要求每一份至少有一个边界
剪一下枝就过了

1226

wc还是爆炸了…
怎么我天天爆炸qaq
假设前面的点都填完了,你发现在某个点没填之前,最多只有长度为7的区间是允许填的
那你就设一个 d p [ i ] [ j ] [ k ] dp[i][j][k] 表示填到第 i i 个点,上一个点是 j j ,向后这个长度为7的区间有哪些是填了的
预处理一个 o k [ i ] [ j ] [ m a s k ] ok[i][j][mask] 表示在第 i i 个点,状态是 m a s k mask ,这时候加入一个 i + j 1 i+j-1 这个点合不合法
转移就枚举下一个点填什么然后转移下去就行了
细节有点多…
主要是 o k ok 数组一开始预处理想错了qaq…

4035

只能
扔一个大爷题解跑路了
要多猜一些结论什么的…
感觉猜结论这方面真的弟弟无比.

4665

我就是个计数弟弟
考虑朴素 2 n 2^n 容斥,枚举至少哪些糖果是一样的
那么有
a n s = ( 1 ) T ( n T ) ! Π ( a [ i ] b [ i ] ) ! ans=\sum(-1)^{|T|}\frac{(n-|T|)!}{\Pi (a[i]-b[i])!}
其中 a [ i ] a[i] 表示第 i i 种糖果有多少个, b [ i ] b[i] 表示选了多少个
这个过程可以dp
设一个 f [ i ] [ j ] f[i][j] 表示前 i i 种糖果,至少有 j j 个是一样的
维护下面的那个逆元积就行了…
过程就选哪些是一样的组合数一下

猜你喜欢

转载自blog.csdn.net/Rose_max/article/details/86497814