2025省选模拟5 T1
看到大家使用优美的记搜方法过掉 T1,我来介绍一种较为独特的方法。
众所周知,我们只需要处理 \(2m\) 个接口(以下称为关键点)。我们将每个关键点拆分成 \(O(n)\) 条信息,分别记录这个点在每个阶段所在的树以及从上个状态到下一阶段是从前半子树(标号不增加的子树)还是后半子树合并来的。例如:我们先把 \(T_0\) 的 \(0\) 号节点连到自己形成 \(T_1\),经过一系列操作后将 \(T_1\) 的 \(1\) 号节点和 \(T_a\) 的某个节点连接形成 \(T_b\),最终 \(T_1\) 的 \(1\) 号节点在 \(T_b\) 上成为了关键点,则我们记录的各个状态所在的树的信息为 \(0 \rightarrow 1 \rightarrow b\),分别是作为后半子树和前半子树合并的。这里有个反常的细节:对于两个不同关键点,如果他们可以到达同一状态,这个状态应当记录多次而非一次。这是一个显然的性质,因为我们把不同关键点的完整前驱状态序列独立地存了起来,但这是我们未来操作正确性的重要条件。
考虑 \(T_a\) 和 \(T_b\) 合并为 \(T\):答案等于 \(T_a\) 和 \(T_b\) 的答案加上两颗树以其对应的接口(即关键点)为根所有点的深度之和与对面点的个数的乘积(分解 \((a+c)+(a+d)+(b+c)+(b+d)=2(a+b)+2(c+d)\),其中 \(a,b\) 为 \(T_a\) 中的,\(c,d\) 反之),再将上两颗树的大小乘积(新形成的路径条数)乘上新边权值。某个点的深度之和需要加上另一棵树接口处的深度之和加上另一棵树节点个数乘上这个关键点与另一棵树接口间的距离。综上所述,我们需要维护每棵树的答案,大小,每个关键点为根的深度之和与两个关键点间距离。前两者很容易维护。先来考虑点间距离。对于每个关键点,维护指针表示这个点的当前状态。每次找到下一状态是 \(T\) 且不是接口的节点,分别加入前半棵树或后半棵树的集合。每次取出两个集合中的点更新另一集合中的每一个点(可以不用处理除了另一棵树内下一状态是 \(T\) 的点以外的点,因为这样的点未来一定与前者无关,即使他是错的也不影响答案。)。更新方式为用两点加上到本树的接口距离再加上新边权值。接下来更新子树内深度和的过程就很显然。为什么要排掉接口?因为这两个接口未来不会再用,对答案没有影响,算上可能会有意想不到的错误(比如合并同一颗树,可能导致同一接口有一个值为新加边的到自己的距离,使得后面距离多加)。
这个解法无需使用递归、哈希表,时间 \(O(n^3)\),空间\(O(n^2)\),虽说码量稍微大些。
Code
#include<bits/stdc++.h>
using namespace std;
const long long p=1000000007;
struct node{
bool opt[800];
int tr[800],tot,cur;
}dot[800];
struct stct{
int sttr,edtr,st,ed;
long long stpt,edpt,val;
}ask[800];
int n,cnt;
long long size[512],sdep[1024],dist[800][800],szst[512],ans[512];
inline void gen(int x,long long x1,int y){
dot[++cnt].tr[0]=y;
for(long long tx=x,tx1=x1;tx;){
dot[cnt].tr[++dot[cnt].tot]=tx;
if(tx1>=szst[tx]) tx1-=szst[tx],tx=ask[tx].edtr;
else tx=ask[tx].sttr,dot[cnt].opt[dot[cnt].tot]=1;
}
++dot[cnt].tot;
int ulim=dot[cnt].tot>>1;
for(int i=0;i<=ulim;++i){
swap(dot[cnt].tr[i],dot[cnt].tr[dot[cnt].tot-i]);
swap(dot[cnt].opt[i],dot[cnt].opt[dot[cnt].tot-i]);
}
}
vector<int> v1,v2;
int main(){
freopen("loquat.in","r",stdin);
freopen("loquat.out","w",stdout);
scanf("%d",&n);
size[0]=1;
for(int i=1;i<=n;++i){
scanf("%d%d%lld%lld%lld",&ask[i].sttr,&ask[i].edtr,&ask[i].stpt,&ask[i].edpt,&ask[i].val);
szst[i]=size[ask[i].sttr];
size[i]=szst[i]+size[ask[i].edtr];
gen(ask[i].sttr,ask[i].stpt,i);
gen(ask[i].edtr,ask[i].edpt,i);
}
memset(size,0,sizeof(size));
size[0]=1;
for(int i=1,x=1,y=2;i<=n;++i,x+=2,y+=2){
int tx=ask[i].sttr,ty=ask[i].edtr;
ans[i]=((((sdep[x]*size[ty]%p+sdep[y]*size[tx]%p)%p+ans[tx])%p+ans[ty])%p+size[tx]*size[ty]%p*ask[i].val%p)%p;
printf("%lld\n",ans[i]);
size[i]=(size[tx]+size[ty])%p;
for(int j=1;j<=cnt;++j){
if(j==x||j==y) continue;
if(dot[j].tr[dot[j].cur+1]==i){
if(dot[j].opt[dot[j].cur+1]) v1.emplace_back(j);
else v2.emplace_back(j);
}
}
for(auto j:v1){
dist[j][y]=dist[j][x]+ask[i].val;
if(dist[j][y]>=p) dist[j][y]-=p;
dist[y][j]=dist[j][y];
for(auto k:v2){
dist[j][k]=dist[j][x]+dist[k][y];
if(dist[j][k]>=p) dist[j][k]-=p;
dist[j][k]+=ask[i].val;
if(dist[j][k]>=p) dist[j][k]-=p;
dist[k][j]=dist[j][k];
}
}
for(auto j:v2){
dist[j][x]=dist[j][y]+ask[i].val;
if(dist[j][x]>=p) dist[j][x]-=p;
dist[x][j]=dist[j][x];
for(auto k:v1){
dist[j][k]=dist[j][y]+dist[k][x];
if(dist[j][k]>=p) dist[j][k]-=p;
dist[j][k]+=ask[i].val;
if(dist[j][k]>=p) dist[j][k]-=p;
dist[k][j]=dist[j][k];
}
}
for(auto j:v1){
sdep[j]=((sdep[j]+dist[j][y]*size[ty]%p)%p+sdep[y])%p;
++dot[j].cur;
}
for(auto j:v2){
sdep[j]=((sdep[j]+dist[j][x]*size[tx]%p)%p+sdep[x])%p;
++dot[j].cur;
}
v1.clear();
v2.clear();
}
return 0;
}
2025省选模拟5 T1的更多相关文章
- 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解
今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...
- 5.15 省选模拟赛 T1 点分治 FFT
LINK:5.15 T1 对于60分的暴力 都很水 就不一一赘述了. 由于是询问所有点的这种信息 确实不太会. 想了一下 如果只是询问子树内的话 dsu on tree还是可以做的. 可以自己思考一下 ...
- NOI 2019 省选模拟赛 T1【JZOJ6082】 染色问题(color) (多项式,数论优化)
题面 一根长为 n 的无色纸条,每个位置依次编号为 1,2,3,-,n ,m 次操作,第 i 次操作把纸条的一段区间 [l,r] (l <= r , l,r ∈ {1,2,3,-,n})涂成颜色 ...
- 洛谷[LnOI2019]长脖子鹿省选模拟赛t1 -> 快速多项式变换
快速多项式 做法:刚拿到此题有点蒙,一开始真没想出来怎么做,于是试着去自己写几个例子. 自己枚举几种情况之后就基本看出来了,其实本题中 n 就是f(m)在m进制下的位数,每项的系数就是f(m)在m进制 ...
- 5.20 省选模拟赛 T1 图 启发式合并 线段树合并 染色计数问题
LINK:图 在说这道题之前吐槽一下今天的日子 520 = 1+1+4+514. /cy 这道题今天做的非常失败 一点分都没拿到手 关键是今天的T3 把我整个人给搞崩了. 先考虑 如果得到了这么一张图 ...
- 5.19 省选模拟赛 T1 小B的棋盘 双指针 性质
LINK:小B的棋盘 考试的时候没有认真的思考 导致没做出来. 容易发现 当k>=n的时候存在无限解 其余都存在有限解 对于30分 容易想到暴力枚举 对称中心 然后 n^2判断. 对于前者 容易 ...
- 【2018.06.26NOIP模拟】T1纪念碑square 【线段树】*
[2018.06.26NOIP模拟]T1纪念碑square 题目描述 2034年,纪念中学决定修建校庆100周年纪念碑,作为杰出校友的你被找了过来,帮校方确定纪念碑的选址. 纪念中学的土地可以看作是一 ...
- 【2020.11.28提高组模拟】T1染色(color)
[2020.11.28提高组模拟]T1染色(color) 题目 题目描述 给定 \(n\),你现在需要给整数 \(1\) 到 \(n\) 进行染色,使得对于所有的 \(1\leq i<j\leq ...
- 省选模拟赛 4.26 T1 dp 线段树优化dp
LINK:T1 算是一道中档题 考试的时候脑残了 不仅没写优化 连暴力都打挂了. 容易发现一个性质 那就是同一格子不会被两种以上的颜色染.(颜色就三种. 通过这个性质就可以进行dp了.先按照左端点排序 ...
- NOI.AC省选模拟赛第一场 T1 (树上高斯消元)
link 很容易对于每个点列出式子 \(f_{x,y}=(f_{x,y-1}+f_{x,y}+f_{x,y+1}+f_{x+1,y})/4\)(边角转移类似,略) 这个转移是相互依赖的就gg了 不过你 ...
随机推荐
- Effective Java理解笔记系列-第1条-何时考虑用静态工厂方法替代构造器?
为什么写这系列博客? 在阅读<Effective Java>这本书时,我发现有许多地方需要仔细认真地慢慢阅读并且在必要时查阅相关资料才能彻底搞懂,相信有些读者在阅读此书时也有类似感受:同时 ...
- ingress配置https报错certificate.lua:259: call(): failed to set DER private key: d2i_PrivateKey_bio() failed, context: ssl_certificate_by_lua*
困扰我2天的报错问题:certificate.lua:259: call(): failed to set DER private key: d2i_PrivateKey_bio() failed, ...
- Go 应用程序使用 dockerfile multi-stage 的问题
场景重现 一个简单的go应用,准备通过docker部署,为了减少运行时的镜像和容器体积,使用了multi-stage构建: # dockerfile 大致如下 # 一级构建使用带golang环境的镜像 ...
- Linux下时区/系统时间/硬件时间的设置
涨姿势,顺带笔记,留爪. 先简述下时区/系统时间/硬件时间的3个主要命令吧 tzselect tzselect命令主要针对时区设置和查看 tz=timezone的缩写,直译=时区 date date命 ...
- 使用 AutoGen Studio 打造你的私有团队
AI Agent 无疑是今年最火爆的概念,从科技巨头的战略布局到创业公司的创新产品,AI 智能体正在重塑我们与机器交互的方式.无论是自动化任务.个性化服务,还是复杂问题的协同解决,AI Agent 都 ...
- Javascript+webdriverio实现app自动化demo
1.新建工程和安装库 使用WebStorm新建一个空项目然后在编辑器打开终端输入如下命令: npm init -y npm install webdriverio npm install sleep ...
- 使用 StreamJsonRpc 在 ASP.NET Core 中启用 JSON-RPC
StreamJsonRpc 是微软开发的一个开源库,用于在 .NET 平台中实现基于 JSON-RPC 2.0 规范 的远程过程调用(RPC).它通过流(如管道.网络流等)实现高效的跨进程或跨网络通信 ...
- Mybatis的原始的执行方式
一.通过SqlSessionFactory创建sqlsession,再由Sqlsession获取session对象,然后通过session中的执行器Executor,去执行MapperStatemen ...
- Git撤销本地commit(未push)
查询commit日志 git log 查询到自己commit的上个版本id(commit_id) 撤销(这里是放弃自己commit的更改,直接回退到上个版本源码) git reset --hard c ...
- 基于OpenCV与PyTorch的智能相册分类器全栈实现教程
引言:为什么需要智能相册分类器? 在数字影像爆炸的时代,每个人的相册都存储着数千张未整理的照片.手动分类不仅耗时,还容易遗漏重要瞬间.本文将手把手教你构建一个基于深度学习的智能相册分类系统,实现: 三 ...