博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JZOJ.5257【NOIP2017模拟8.11】小X的佛光
阅读量:7200 次
发布时间:2019-06-29

本文共 2944 字,大约阅读时间需要 9 分钟。

Description

 

Input

Output

 

Sample Input

3 3 11 22 31 2 31 1 33 1 3

Sample Output

113
 

Data Constraint

题目就是要求两点到一个点的路径中重叠的点的个数。

特殊性质一是一条链,我们可以通过讨论两个起点和一个终点的相对位置直接得出答案。

特殊性质二的两个起点相同,就是要我们求树上两点之间的点的个数,求出两点LCA,预处理点到根节点的距离,再根据LCA是不是根节点决定距离相减或相加就可以了。

考虑100分的,仍然要LCA,然后分类讨论就可以了......

我们记num[i]为i到根节点的点的个数(包括根节点和它自己)

第一种是LCAab和LCAcb相等,那么我们求LCAac,答案就是num[LCAac]+num[B]-num[LCAab]+1。(这里的一个点到根节点的个数包括根节点和它本身。)

第二种是LCAab和LCAcb不相等,如果LCAab和LCAcb中有一个是B的,那么答案就是1,如果都不是B,那么我们再求LCALCAab LCAcb这个时候它们的LCA必是其中的一个(可用反证法证明),如果是LCAab,那么答案就是num[B]-num[LCAcb]+1,否则就是LCAcb,答案为num[B]-num[LCAab]+1。

LCA用树上倍增或者欧拉迹+ST就可以啦(欧拉迹数组似乎要开很大QAQRE好久)

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #define N 600001 8 using namespace std; 9 int n,m,p,t,ans,head[N*2],next[N*2],to[N*2],visit[N],deep[N*2],ji[N*2],num,ti,ge[N],f[N][100],qwq[N][100];10 void add(int u,int v){11 num++;12 next[num]=head[u];13 to[num]=v;14 head[u]=num;15 num++;16 next[num]=head[v];17 to[num]=u;18 head[v]=num;19 }20 void dfs(int x,int nu,int d){21 if (!visit[x]) visit[x]=++ti;22 ji[ti]=x;23 deep[ti]=d;24 ge[x]=nu;25 for (int i=head[x],v;i!=0;i=next[i]){26 v=to[i];27 if (!visit[v]) {28 dfs(v,nu+1,d+1);29 ji[++ti]=x;30 deep[ti]=d; 31 }32 }33 }34 void ST(){35 int tmp=(int)(log(ti)/log(2));36 for (int i=1;i<=ti;i++){37 f[i][0]=deep[i];38 qwq[i][0]=ji[i];39 }40 for (int j=1;j<=tmp;j++)41 for (int i=1;i<=ti;i++){42 int k=1<<(j-1);43 if (i-k<=ti)44 if (f[i][j-1]
神奇的代码

(似乎JZ评测集下会爆栈...根节点设为n/2也可以)(明明20万数据莫名60万才过了QAQ)

还有一个水水的程序(输入数据还好良心,告诉你性质)

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #define N 500001 8 using namespace std; 9 int n,m,p,t,ans,head[N*2],next[N*2],to[N*2],visit[N],deep[N*2],ji[N*2],num,ti,ge[N],f[N][100],qwq[N][100]; 10 void add(int u,int v){ 11 num++; 12 next[num]=head[u]; 13 to[num]=v; 14 head[u]=num; 15 num++; 16 next[num]=head[v]; 17 to[num]=u; 18 head[v]=num; 19 } 20 void shui1(){ 21 for (int i=1,u,v,w;i<=m;i++){ 22 scanf("%d%d%d",&u,&v,&w); 23 if ((v>=u)&&(v>=w)) printf("%d\n",v-max(u,w)+1); 24 else if (((v>=u)&&(v<=w))||(v<=u)&&v>=w) printf("1\n"); 25 else if ((v<=u)&&(v<=w)) printf("%d\n",min(u,w)-v+1); 26 } 27 } 28 void dfs(int x,int nu,int d){ 29 if (!visit[x]) visit[x]=++ti; 30 ji[ti]=x; 31 deep[ti]=d; 32 ge[x]=nu; 33 for (int i=head[x],v;i!=0;i=next[i]){ 34 v=to[i]; 35 if (!visit[v]) { 36 dfs(v,nu+1,d+1); 37 ji[++ti]=x; 38 deep[ti]=d; 39 } 40 } 41 } 42 void ST(){ 43 int tmp=(int)(log(ti)/log(2)); 44 for (int i=1;i<=ti;i++){ 45 f[i][0]=deep[i]; 46 qwq[i][0]=ji[i]; 47 } 48 for (int j=1;j<=tmp;j++) 49 for (int i=1;i<=ti;i++){ 50 int k=1<<(j-1); 51 if (i-k<=ti) 52 if (f[i][j-1]
水水程序

 

转载于:https://www.cnblogs.com/Lanly/p/7348657.html

你可能感兴趣的文章
php
查看>>
开发 Linux 命令行实用程序
查看>>
我的友情链接
查看>>
使用Symantec Backup Exec 对Exchange 2010 进行备份还原和灾难恢复系列之一
查看>>
[培训]薛大龙@福建福州(2008.7.24-25)
查看>>
Linux运维学习历程-第十四天-磁盘管理(一)磁盘分区表类型与文件系统
查看>>
2016年4月20日作业
查看>>
4、Ansible配置和使用
查看>>
如何设计EDM邮件内容
查看>>
java_类型转换(转)
查看>>
EMC 存储 故障转移模式(Failover Mode)简介
查看>>
解决iis服务器 Server Application Error
查看>>
MySQL5.7杀手级新特性:GTID原理与实战
查看>>
typeahead自动补全插件的limit参数问题
查看>>
关于foreach总是报错invalid param等问题
查看>>
bash快捷方式
查看>>
php DOC类型注释的用法
查看>>
浏览器兼容问题踩坑收集
查看>>
H5视频推流方案
查看>>
【BZOJ】3998: [TJOI2015]弦论
查看>>