春思
先看出来是个等比数列取模的题目
然后拆一下质因数
因为不会等比数列求和取模,所以炸了
现在学了一下,就是分奇偶情况讨论即可
inline int calc(int x,int y){
if(!y) return 1;
if(y&1){
int res=calc(x,y>>1);
res=add(res,mul(res,ksm(x,(y+1)>>1)));
return res;
}else{
int res=calc(x,(y-1)>>1);
res=add(res,mul(res,ksm(x,(y>>1)+1)));
res=add(res,ksm(x,y>>1));
return res;
}
}
666
比较有意思的题目
发现每次加上 (1) 倍的费用是 (2) ,加上 (2) 倍的费用是 (3)……
剪 (1) 的费用是 (1)
那么跑最短路即可
这里有个结论那样子,只有 (2,3,5,7) 倍有用,具体证明可以感性理解一下吧,比如 (11) 倍可以 (4 imes3-1)
但是 (7) 就并不能凑得到更小的值
当然,显式是spfa好像只有发 (30) 那样子
所以考虑广搜实现 (dp) 即可
(我的代码习惯垃圾,需要卡常)
密州盛宴
转化出来题意之后,代码难度大概在 (CF Div2 B o C)
题意也并不难转化
赤壁情
(ZJOI2012) 波浪
定义 (f_{i,j,k,l}) 为放了前 (i) 个数,所有的贡献是 (j),(k) 个连续段,(l) 个点在边界上
这里考虑所有的数是顺次插入的,那么每个数对总答案的贡献可以按照顺序给正负
去绝对值的手段:按照数值顺序加入
转移的时候考虑合并两个连续段,添加一个连续段,放到一个段的末尾
但是按照EI的话 “魔鬼在细节”
这里需要考虑所有 (l) 的情况
转移很复杂,手推即可(wdwmd)
最后的答案很大,所以要开 (\_\_float128)
具体转移这么写:
((1)) 新增一个段
((2)) 合并两个段
((3)) 放到段尾
((4)) 放到一边且不相连
((5)) 放到一边且相连
大佬
直接考虑有多少种情况满足 (len=k,mx=i)
(i^k-(i-1)^k)
然后乘上天数和权重最后除掉总情况就没了
分组
因为两个数的和很小,那么找 (500) 以内的平方减掉就行了
用 (set) 判一下就能解决 (k=1) 的部分分
关于 (k=2) 关押罪犯即可
如果 (kge 2) 那么考虑大力拆点吧,跟那个食物链有点像
路径计数
不错呢,原来是怵计数,现在可以说是又爱又恨了
正常来讲,直接两头删,就是个二叉树,那么路径数应该是 (2^{len}-1)
观察一下样例给的图,发现这里面 (bb o b) 的那部分并不够这个答案
那么容斥一下相邻字符重复的情况
设中间有 (len) 个重复的,左边有 (x) 个,右边有 (y) 个
则原来到达只剩下 重复字符 的方案数是 (sumlimits_{i=0}^{len-1}sumlimits_{j=0}^{len-i-1} inom{x+i+y+j}{x+i})
(咱看到了 (ATCoder)上 (BBQHard) 的影子,但是发现复杂度并不对)
想办法把解决这部分的复杂度降下来,那么可能是枚举左边删掉几个,然后对右边删除的方案直接求和
换一种理解方式:枚举剩下的量((len-i)),考虑删除的方式
(这部分给我想自闭了)
然后加上当前的答案,枚举走到 (len-i) 的时刻得到方案数,注意 (i=0) 的情况
诚然,这题确实是很好的题目
宇宙飞船
玩了几次(注意,是”次“)样例之后发现可以转到编号上来做
做一个置换之后变成了求以某个点为开始的最长下降和以该点为结束的最长上升子序列的长度和的最大值
两遍 (LIS) 即可
(上来先做计数题是什么垃圾顺序)
括号序列
设 (s_i) 为前 (i) 个里面左括号减掉右括号的值
如果一子串 ([l,r]) 满足所有的 (s_ige s_l,s_r=s_l)
那么它是一个合法子串
单调栈求控制区间然后看里面有多少个值相同的点即可
这部分发现好像复杂度是有问题的
考虑每个点的加入对区间们的影响
小于当前点的是没有影响的,大于的就结束了
最显然的做法是走个线段树
与
题目要求与起来一样的方案数,然后午休的时候想到了这个式子
这里 (c_i) 表示至少有 (i) 位一样的方案数
然后问题转化成如何记这个数
枚举哪些位置需要相等,然后容斥上去
然而限制这些位置需要相等其实是并不好做的,不如限制不想等
并查集合并即可
理解了容斥原理的本质
Balanced Diet
首先考虑 (forever) 的情况
考虑每个种类的糖果的上下边界,贪心维护一下即可
如果出现:((n+1)f_i-1>s_i) 那么就得在当前的状态下买一个这种糖果
同时如果 ((n+1)f_i+1le s_i) 就不能买
那么我会推式子!
已知当前的 (s_i) ,下一个不能够的点的位置应该是 (lfloorfrac{s_i+1}{f_i} floor),能够的点是 (add(frac{s_i-1} {f_i})-1)
这里的 (add) 就是整数进一,不是整数的上取整
那么从小到大维护所有的数的下一个点,如果有多个点要买或者没的买,那么退出去
异或
如果把题目下放到位,然后转化成一个计数题目
求有多少个数对能满足这个位是 (1)
维护在区间里面有多少个数字满足这个位是 (1)
所以乘起来再乘上权值就行了
取石子
看题面发现是个博弈题目
然后觉得这东西按照 (sg) 的方式直接判定就行了
一开始忘记 (f_{0,0,0}) 了就挂了几次
串串香
循环节问题,因为手残:(%) 打成 (&) 挂了几次
Tiny Counting
直接顺逆序对容斥即可
糊涂图
式子有点多,简单梳理一下
定义 (f_i) 为从 (i) 开始的胜率,那么没有出度的所有点 (x), 自然有 (f_x=0)
转移比较好说
如果加入了一条边,如果这条边不能被 (s) 经过,那么不管
那么要处理从 (s) 开始每个点的到达概率 (ar_i)
显然有 (ar_s=1), 别的顺着做就行了
考虑到
也就是说总的获胜概率为经过 (i) 点的概率乘上经过 (i) 点获胜的概率加不经过 (i) 点的概率乘上不经过 (i) 点获胜的概率 (f_{!i})
同时用 (arr_{0/1}) 表示到点 (i) 用偶数步还是奇数步的概率
这里的 (f_{!i}) 的做法直接用 (f_s) 推一下
写代码的时候注意转这里的精度
这些就都可以直接拓扑做
然后先考虑第一问最大值
考虑加边 ((i,j)) 之后有 (newf_i=frac{du_i}{du_i+1} imes f_i+frac 1{du_i+1} (1-f_j))
问题转化为了求这个 (newf_i) 套进原来式子之后的最大值
那么维护一个 (f_{min},f_{max})
就能做了
枚举所有点,比较 (arr1_i,arr0_i)
再来第二问
本质上就是对所有的 (newf_i) 套进去求和再除掉
拆开所有项,分别维护即可
orz当场切掉这题目的 (pl.er())
A
原来做过二次函数从对称轴拓展的,但是并不能用在这题目上面
二次项挺烦的,那么降次
分到两边除掉 (x)
后面的问题变成了给定平面上好多直线,求一给定的 (x) 的最大/最小值问题
超哥线段树解决即可
复兴了:李超线段树(不是作死是啥……)
这里被坑了几下:
printf("%lld
",0);
这种写法显然是完蛋的
木叶下
题目转化成了删掉一个环之后的树上最长链,或者直径除掉(2)
连边之后和会影响到 (x,y,lca(x,y)),那么答案就是当前链上伸出的最长链或者当前直径 (/2)
其实这题目做了半天不太会的地方就是怎么处理棵树上去掉当前链的最长链
然后想明白了:就维护就行了……
然后就维护就行了,分类讨论取答案即可
strGame
没咋写过博弈题,只知道基础的 (SG) 函数转移
这题目显然建立 (trie) 树之后就可以转移了,从地下向上面即可
然后判断根节点的情况和 (k) 的奇偶性
但是这并不能覆盖所有胜利条件,所以拆成 (4) 个状态即可
Huge Counting
发现这个 (f) 函数本质是从高维空间里面的点转移到 $f(1,1dots,1) $ 的方案数
数形结合完了发现可能就是个多重集排列的奇偶性
即
然后发现这东西并不能做到题目里面的复杂度
以下颓了题解……这个转化简直想不到
说想不到?其实如果从复杂度那边推,也能找到点端倪吧
不过这个结论是真的收获了
如果满足每个 (x_i&x_j=0), 那么 (f(x_1,dots x_n)=1)
所以数位 (dp) 考虑把 (1) 放到哪个位置就行了
考虑维护是不是超过了限制的话可以用二进制来,省得麻烦