训练纪要贰
安静的开发间接费历史记录。
NOIP-Ax 是大联测,CSP-联x 是小联测,CSP-x 是自己测。
10.3 Thur.
上午模拟赛
下午改题的时候发现自己当时确实理解不透,导致今天还得重新理解一遍。
后来又做了几道板子啊,一个放假前模拟赛放的斯坦纳树的板子,一个放在 vjudge 题单里我忘了自己写过又写了一遍的线段树分裂的板子,还有一个题单里很一眼的树剖。写点水的就写点水的吧。
体活是好的,喜欢打羽毛球,如果之后有大把时间并且没有别人(怕丢脸)的话,想去打篮球了。
机房里闷死了,脑袋疼。
NOIP-A01
A.构造字符串
对于一条限制,相当于两段区间
B.寻宝
直接搜一遍连通块,然后传送门相当于是连通块之间的单向边。由于
C.序列
对
所以扫描线
D.构树
首先有扩展 Cayley 公式:
所以就有 DP 设
考虑优化这个 DP,根据一个大家都说很典所以我也说很典但是实际上除了这个题我没见过的一个转化,将第二维改为
点击查看代码
for(int i=siz[x]-1;~i;--i)
{
for(int j=siz[y]-1;~j;--j)
{
ll x0=f[x][0][i],x1=f[x][1][i];
ll y0=f[y][0][j],y1=f[y][1][j];
//选这条边,贡献到 i+j+1
M(tmp[0][i+j+1],x0*y0%mod);
M(tmp[1][i+j+1],(x0*y1+x1*y0)%mod);
//不选这条边,贡献到 i+j
M(tmp[0][i+j],n*x0%mod*y1%mod);
M(tmp[1][i+j],n*x1%mod*y1%mod);
//不选这条边,贡献减到 i+j
M(tmp[0][i+j],mod-x0*y0%mod);
M(tmp[1][i+j],mod-(x0*y1+x1*y0)%mod);
}
}
P6192 【模板】最小斯坦纳树
设
直接转移不太行,发现第一种转移类似松弛操作,所以类似 dij 转移。至于第二种就直接在确定一个
总时间复杂度
P7735 [NOI2021] 轻重边
直接树剖,对轻重边(指树剖的轻重边)分开考虑,将边挂到下方点上。
直接线段树维护重边是否合法;对于轻边,我们记一下它最后一次合法的时间戳,所以还需要对每个点维护它最后一次使与它相连的边都不合法的时间戳。
修改的时候路径所有点的时间戳都要更新,每个链头往上跳经过的轻边也要记一下时间戳,每次更新一条链
10.4 Fri.
上午模拟赛
感觉很大的问题是不敢想不敢试啊。感觉好多时候都是想到一半不敢接着深挖了。T2 明明不难赛时还是没有大胆做,T3 开始猜出来了那个栈的思路,后面想直接线段树维护区间栈的信息直接合并发现合并不了,在想是不是还要转化一步,结果摆了,尽管再尝试转化也做不出来。
CSP-联02
A.挤压
平方相当于二进制上同时为
设
B.工地难题
考虑计算最长连续段长度小于等于
总共有
先枚举
所以
C.星空遗迹
好题!先考虑怎么线性做询问,定义
首先连续的相同元素的个数并不重要,可以看成一个元素。
考虑从
就是插入一个数的时候,能被栈顶元素赢的话就把它放在栈顶。因为比方说现在栈顶是 R,下一个元素是 P,那么 R 就输了;但是如果中间有一个 S,那么 S 就可以赢 P 了,R 也就不输了。
我赛时想到这个的思路太抽象(甚至我在解释的时候会提到“护盾”一词),所以没法更严谨的说了,自己意会吧。
接下来肯定要用数据结构来优化这个,直接优化不太现实,但是我们设加入
解释一下最后一行的
那么答案就是最后一个
发现
那么现在问题变成了后缀加,区间查最小值位置,线段树维护。
D.纽带
是因为这个题复杂所以我写的更详细吗?
省流:析合树
首先类似析合树,我们要定义一些东西,这些东西不与传统析合树完全相同,所以性质也不与传统析合树完全相同。
定义满足题目中的限制,即满足
称不与其它连续段部分相交的段为本原段,所以本原段与其他连续段的关系只能是包含关系。
既然所有的本原段之间只有包含关系,我们就可以将所有本原段拿出来作为一棵树。
将所有本原段进一步分作合点和析点,合点指任取它的连续的几个儿子,总能组成新连续段;析点则是总不能组成连续段。
可并不是所有叶子都是连续段,我们将
那么合点的儿子只能是析点,因为若合点
析点的孩子则既可以是析点也可以是合点,甚至可以是非法叶子,不过每两个合析点中间都至少有一个非法叶子,不然这两个儿子拼在一起就形成连续段了。头尾也必须是非法叶子,不然假设头部是一个连续段,那么除去这个连续段其它的儿子拼起来就会形成一个连续段。
那么我们基本就可以开始 DP 了,不过我们仍无法计算在析点中放入了
因为它是析点,所以即使几个非空叶子相邻也不能是连续段。所以这一部分的方案数就相当于是长度为
(这里有一段递推
然后就可以直接区间 DP 转移了,设
转移直接区间 DP 枚举区间,然后对于
先转移
还有细节也写一下吧,无论是
然后你发现复杂度
将
这个优化相当于是你在 DP 的时候可以不用枚举转移的连续段个数和转移后的连续段个数,这相当于少了
至于点值转系数,你可以选择直接对着那个式子暴力卷积,最终是
点击查看代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string.h>
#define ll long long
using namespace std;
const int N=45,mod=1e9+7;
int n,m,M[N];ll A[825],P[N],I[825],Y[825],ANS[825];
ll f[N][N][N],g[N][N][N],F[N][N],G[N][N],H[825];
inline void Mod(ll &x,int y){x+=y;if(x>=mod) x-=mod;}
inline ll ksm(ll a,int b=mod-2)
{
ll ans=1;for(;b;b>>=1,a=a*a%mod)
if(b&1) ans=ans*a%mod;return ans;
}
signed main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
cin.tie(0),cout.tie(0);
ios::sync_with_stdio(0);
cin>>n,m=n*(n+1)/2,A[0]=A[1]=P[0]=I[0]=I[1]=1;
for(int i=2;i<=m;++i)
{
A[i]=(i-1)*A[i-1]%mod;
for(int j=2;j<=i-2;++j)
A[i]+=(j-1)*A[j]%mod*A[i-j]%mod;
A[i]%=mod,I[i]=ksm(i);
}
for(int i=1;i<=n;++i) cin>>M[i];
for(int x=1;x<=m+1;++x)//多项式代入值
{
memset(f,0,sizeof(f)),memset(g,0,sizeof(g));
memset(F,0,sizeof(F)),memset(G,0,sizeof(G));
for(int i=1;i<=n;++i)
{
P[i]=P[i-1]*x%mod;
f[i][i-1][0]=g[i][i][1]=1;
if(i>M[i]) f[i][i][1]=G[i][i]=x;
}
for(int len=2;len<=n;++len)//枚举区间长度
{
for(int l=1;l+len-1<=n;++l)//枚举区间左端点
{
int r=l+len-1;//区间右端点
//析点更新
for(int i=l+1;i<r;++i)//枚举最后一次转移,选择一个段 [i,r-1] + 叶子
for(int c=1;c<=r-l+1;++c)//枚举选了多少叶子
Mod(g[l][r][c],g[l][i-1][c-1]*(F[i][r-1]+G[i][r-1])%mod);
for(int c=1;c<=r-l+1;++c)//枚举选了多少叶子
Mod(g[l][r][c],g[l][r-1][c-1]);
if(r<=M[l]) continue;
for(int c=2;c<=r-l+1;++c)
Mod(G[l][r],g[l][r][c]*A[c]%mod*x%mod);
//合点更新
for(int i=l;i<=r;++i)//枚举最后一次转移,选择一个析点 [i,r]
for(int c=1;c<=r-l+1;++c)//枚举选了多少儿子
Mod(f[l][r][c],f[l][i-1][c-1]*G[i][r]%mod*P[c-1]%mod);
for(int c=2;c<=r-l+1;++c)
Mod(F[l][r],f[l][r][c]);
}
}
Y[x]=(F[1][n]+G[1][n])%mod;
//拉插求系数(暴力卷积)
memset(H,0,sizeof(H)),H[0]=1;ll C=Y[x];
for(int i=1;i<=m+1;++i)
{
if(i==x) continue;C=C*I[abs(x-i)]%mod*(x>=i?1:-1);
for(int j=i;~j;--j)
{H[j]=H[j]*(-i)%mod;if(j) H[j]=(H[j]+H[j-1])%mod;}
}
for(int i=1;i<=m;++i) ANS[i]+=C*H[i]%mod;
}
for(int i=1;i<=m;++i) cout<<(ANS[i]%mod+mod)%mod<<' ';
cout<<'\n';return 0;
}
10.5 Sat.
发现开始写训练纪要的确促进我改题了,另一个促进是旁边的 5k 和队奶。
上午把昨天 T4 改了,然后开了道串,被恶心到了,扔了。然后过去了多半个上午了。
后来啊,后来就去看别人游记和自己游记了。
明天下午有 CF Div2,爽了,希望不会出岔子。
下午把昨天 T4 题解补了,但是好像不是很会
怎么又开始摆烂了。晚上拿小号打 ABC。
CF995F Cowmpany Cowmpensation
拉插优化 DP 板子?
简单 DP,设
发现
P4463 [集训队互测 2012] calc
咕咕咕。
ABC347F Shipping
不难发现一次发出一定是
设
转移时枚举
10.6 Sun.
上午模拟赛 .in
和 .ans
放反了硬控我中午吃饭时间。
下午非常好 CF,C1 吃了发罚时,34 min 过完 C2。发现 D 题过得没 E1 多就去做 E 了,想了一会想到 kruskal 重构树,但是想先想
开始期待下一场 20 号正常点 CF 了,不过我打 Div1 上过分吗?
之后先改 T4 被控了半天,后来发现错了一堆,其中最唐的是叉乘求面积没取绝对值。于是题好像改不完了,这下有事干了。
题解是之后才补得,好水。
折叠起来的一些闲话
最近发现心情并不糟糕了,对奥赛重新乐在其中了。
感觉最大的原因是训 NOIP 没有对自己打击这么大,去年训省选甚至都还好。但是开始训国赛(甚至我没法打国赛)尤其是打 nfls 的时候每天打击就很大了,也是心情最不好的时候。
趁着现在心情好抓紧提升自己吧,省的明年到了那个时候又天天破防,都高二了破防肯定得比高一严重。
其实最近真的能够感觉出来自己在提升,这种感觉是很久没有过的了,这种感觉可能是跟心情好相辅相成的吧。
CSP-09
A.邻面合并
要将一行中的分割线压下来,可以根据分割线解出来唯一的最后一行的连续段分布方式,一个连续段指的是在一行中的在同一矩形中的极长区间。
转移时枚举上一行状态和当前行状态,一个连续段如果在上一行不是连续段就有
B.光线追踪
询问向量与矩形只有可能交在矩形的底边或左侧边上,对着两种情况分开考虑。
考虑与底边相交,能与一个矩形相交的斜率是一段区间,同一斜率最先交到的是底边纵坐标最小的矩形。
所以把询问向量的斜率拿出来离散化当做线段树下标,加入矩形相当于区间取 min,查询是单点查最小值编号。
C.百鸽笼
拒绝采样法,每一列进满以后也能进,进去以后相当于要再进一次,与原问题一致。操作序列中最后一个被进满的就是答案。
设
发现容斥系数只与
设
依次考虑每一列
最后将
这时只考虑了
发现实际上就是把
D.滑稽树下你和我
计算几何,没啥意思,改了但不写题解。
10.7 Mon.
上午模拟赛
下午改今天 T4,昨天 T3,在 CF 上发表言论,补一补博客,但是感觉补得很仓促,无所谓了。
huge 说让我和 5k 出一个人当代表发言,rand
输了,都怪涛哥手气差。
NOIP-A03
A.五彩斑斓
枚举矩形的左边界
当
当
B.错峰旅行
扫描线。(我不理解放这个干啥,我打的不是普及组啊?)
C.线段树
记
区间 DP,设
D.量子隧穿问题
发现是一个内向基环树森林(我赛时没看出来?)。首先不跟
考虑是树咋做。设
按顺序处理
考虑原问题的基环树,只需要讨论环上第一次操作的情况,即钦定合并完后
CF2021E3 Digital Village (Extreme Version)
其实赛时已经转化完了,但是我并不知道可以用闵可夫斯基和优化
考虑建出 kruskal 重构树,设
转移时合并两个子树
所以实际上我们每次转移后
我们考虑记录
10.8 Tues.
别人开学以后就又要跑操了,我还是喜欢没人的学校。
还有你吃饭时间统一改成啥了?建议以后谁定吃饭点谁跟我们一起吃饭,再配个人去查你看你能不能来得及上床。
当然来得及,只是一点别的时间都没有了。
上午模拟赛
发现自己现在还是畏难心里比较严重,是不是应该强迫自己做点难题。
还有感觉现在做的很多题都跟正赛偏不少啊,可能得多刷点更为接近的。
而且他模拟赛这么放,我现在都搞不清楚 NOIP 啥难度,我都没有考场策略了。
但其实对于我不紧张比有策略重要吧,一有策略就容易紧张怎么办?
晚上比较颓啊,明天开个比赛 VP 吧,还没想好是啥我去,有模拟赛啊。
CSP-10
A.欧几里得的噩梦
不喜欢这个题,不想写题解。
B.清扫
先选一个非叶子点当根。从叶子到根合并,当位于
C.购物
发现当
进而可以得到
所以记
而当
D.ants
先想到莫队。带
记
CF2021D Boss,Thirsty
原来就是直接做啊。
记
设
考虑直接求
计算四个括号里的东西即可,注意能否取等,这意味着一些计算的先后顺序。第一行要特殊处理。
10.9 Wedn.
昨天晚上听说要买 nfls 题打,你怎么知道我这几天有这个想法。
毕竟这模拟赛吧,也不是很烂啊,只能说每天就随便放一场,好不好听天由命,难不难命中注定。也没什么标准,给我打的挺迷糊的。nfls 可能会好的多吧。
上午模拟赛
下午先写了一会脚本,大概是想要在洛谷似掉的时候自己跳到 vjudge。后来把 T4 改了。
晚上和 K8 due。我:“啥是 due?”,K8:“……咱俩限定一个难度范围……”,开了道 2400,结果是唐题,大概是放模拟赛 T1 大家全都过的题。
感觉有点累,晚上也睡不着觉,歇一会。
快让我打 nfls!
NOIP-A04
A.02表示法
直接递归做,要实现高精右移。
B.子串的子串
我用 SAM 做 NOIP 字符串哈希题。
直接对
所以说把询问挂在右端点上,加入
C.魔法咒语
考虑正反建出两棵 Trie 树,发现一个合法串可能被计算多次,于是钦定在所有合法方案中第一个串最长的方案中统计答案。算不到单个串的情况,最后单独加上。
所以遍历一棵 Trie 树上的所有节点
测大样例发现不对啊,有个 Corner Case。发现我们要求非空,所以如果有一个合法字符串
D.表达式
当模数较小,可以在线段树上每个节点维护一个映射,表示当值为
原题保证了模数分解质因数后质因数个数不多且
CF1866L Lihmuf Balling
我不理解啊,这玩意洛谷甚至评了紫,那我还是写一下。
直接枚举
10.10 Thur.
没有模拟赛,想开 UNR VP 的。
结果看到官网发了省队名额测算的具体常量值,研究了一会,翻了翻去年成绩,时间就不够了,惋惜啊。
vjudge 图论题单不是很想刷,尽管发现自己平常不做什么图论题,考试一考啥也不会。
但是后来发现实在没意思,先 VP 场 CFDiv1 吧,因为上了 Master 过几天打不了 Div2。
结果给我打破防了,A 题过了以后,B 题绿题就不会!!!扔给涛哥和 luobotianle 一会就过了,这咋整?
其实今天本来打算的就是好好歇歇,没休息好有点难受。
CF1889B Doremy's Connecting Plan
若
所以只考虑跟
CF1889C2 Doremy's Drying Plan (Hard Version)
设
考虑转变为枚举
问题转化成区间 RMQ,末尾插入,维护反 ST 表即可。
CF1889D Game of Stacks
好题。
当每个栈大小为
扩展到一般情况也是一样的,只需要每次找到环时把环删掉,把环上每个点出度指向的点更新即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下