JZOJ.5257【NOIP2017模拟8.11】小X的佛光
Description
Input
Output
Sample Input
3 3 1
1 2
2 3
1 2 3
1 1 3
3 1 3
Sample Output
1
1
3
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好久)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define N 600001
using namespace std;
int n,m,p,t,ans,head[N*],next[N*],to[N*],visit[N],deep[N*],ji[N*],num,ti,ge[N],f[N][],qwq[N][];
void add(int u,int v){
num++;
next[num]=head[u];
to[num]=v;
head[u]=num;
num++;
next[num]=head[v];
to[num]=u;
head[v]=num;
}
void dfs(int x,int nu,int d){
if (!visit[x]) visit[x]=++ti;
ji[ti]=x;
deep[ti]=d;
ge[x]=nu;
for (int i=head[x],v;i!=;i=next[i]){
v=to[i];
if (!visit[v]) {
dfs(v,nu+,d+);
ji[++ti]=x;
deep[ti]=d;
}
}
}
void ST(){
int tmp=(int)(log(ti)/log());
for (int i=;i<=ti;i++){
f[i][]=deep[i];
qwq[i][]=ji[i];
}
for (int j=;j<=tmp;j++)
for (int i=;i<=ti;i++){
int k=<<(j-);
if (i-k<=ti)
if (f[i][j-]<f[i+k][j-]){
f[i][j]=f[i][j-];
qwq[i][j]=qwq[i][j-];
}
else{
f[i][j]=f[i+k][j-];
qwq[i][j]=qwq[i+k][j-];
}
}
}
int lca(int x,int y){
int a=min(visit[x],visit[y]);
int b=max(visit[y],visit[x]);
int tmp=(int)(log((b-a)+)/log());
if (f[a][tmp]<f[b-(<<(tmp))+][tmp])
return qwq[a][tmp];
else return qwq[b-(<<(tmp))+][tmp];
}
void work(int a,int b,int c){
int d=,e=;
d=lca(a,b);
e=lca(b,c);
if (d==e){
int x=lca(a,c);
printf("%d\n",ge[x]+ge[b]-*ge[d]+);
}
else if ((d==b)||(e==b)) printf("1\n");
else {
int x=lca(d,e);
if (x==d) printf("%d\n",ge[b]-ge[e]+);
else if (x==e) printf("%d\n",ge[b]-ge[d]+);
}
}
int main(){
scanf("%d%d%d",&n,&m,&p);
for (int i=,u,v;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);
}
dfs(,,);
ST();
for (int i=,u,v,w;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
work(u,v,w);
}
return ;
}
神奇的代码
(似乎JZ评测集下会爆栈...根节点设为n/2也可以)(明明20万数据莫名60万才过了QAQ)
还有一个水水的程序(输入数据还好良心,告诉你性质)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define N 500001
using namespace std;
int n,m,p,t,ans,head[N*],next[N*],to[N*],visit[N],deep[N*],ji[N*],num,ti,ge[N],f[N][],qwq[N][];
void add(int u,int v){
num++;
next[num]=head[u];
to[num]=v;
head[u]=num;
num++;
next[num]=head[v];
to[num]=u;
head[v]=num;
}
void shui1(){
for (int i=,u,v,w;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
if ((v>=u)&&(v>=w)) printf("%d\n",v-max(u,w)+);
else if (((v>=u)&&(v<=w))||(v<=u)&&v>=w) printf("1\n");
else if ((v<=u)&&(v<=w)) printf("%d\n",min(u,w)-v+);
}
}
void dfs(int x,int nu,int d){
if (!visit[x]) visit[x]=++ti;
ji[ti]=x;
deep[ti]=d;
ge[x]=nu;
for (int i=head[x],v;i!=;i=next[i]){
v=to[i];
if (!visit[v]) {
dfs(v,nu+,d+);
ji[++ti]=x;
deep[ti]=d;
}
}
}
void ST(){
int tmp=(int)(log(ti)/log());
for (int i=;i<=ti;i++){
f[i][]=deep[i];
qwq[i][]=ji[i];
}
for (int j=;j<=tmp;j++)
for (int i=;i<=ti;i++){
int k=<<(j-);
if (i-k<=ti)
if (f[i][j-]<f[i+k][j-]){
f[i][j]=f[i][j-];
qwq[i][j]=qwq[i][j-];
}
else{
f[i][j]=f[i+k][j-];
qwq[i][j]=qwq[i+k][j-];
}
}
}
int lca(int x,int y){
int a=min(visit[x],visit[y]);
int b=max(visit[y],visit[x]);
int tmp=(int)(log((b-a)+)/log());
if (f[a][tmp]<f[b-(<<(tmp))+][tmp])
return qwq[a][tmp];
else return qwq[b-(<<(tmp))+][tmp];
}
void shui2(){
for (int i=,u,v,w,x;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
x=lca(u,v);
if (x==) printf("%d\n",ge[u]+ge[v]-);
else printf("%d\n",ge[u]+ge[v]-*ge[x]+);
}
}
void work(int a,int b,int c){
int d=,e=;
d=lca(a,b);
e=lca(b,c);
if (d==e){
int x=lca(a,c);
printf("%d\n",ge[x]+ge[b]-*ge[d]+);
}
else if ((d==b)||(e==b)) printf("1\n");
else {
int x=lca(d,e);
if (x==d) printf("%d\n",ge[b]-ge[e]+);
else if (x==e) printf("%d\n",ge[b]-ge[d]+);
}
}
int main(){
scanf("%d%d%d",&n,&m,&p);
for (int i=,u,v;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);
}
if ((p==)||(p==)||(p==)||(p==)||(p==)){
shui1(); return ;
}
ti=;
dfs(,,);
ST();
if ((p==)||(p==)||(p==)){
shui2(); return ;
}
for (int i=,u,v,w;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
work(u,v,w);
}
return ;
}
水水程序
JZOJ.5257【NOIP2017模拟8.11】小X的佛光的更多相关文章
- JZOJ.5258【NOIP2017模拟8.11】友好数对
Description
- [jzoj 5343] [NOIP2017模拟9.3A组] 健美猫 解题报告 (差分)
题目链接: http://172.16.0.132/senior/#main/show/5343 题目: 题解: 记旋转i次之后的答案为$ans_i$,分别考虑每个元素对ans数组的贡献 若$s_i& ...
- 常州模拟赛d2t3 小X的佛光
平日里最喜欢做的事就是蒸发学水.[题目描述]小 X 所在的城市 X 城是一个含有 N 个节点的无向图,同时,由于 X 国是一个发展中国家,为了节约城市建设的经费,X 国首相在建造 X 城时只建造 N ...
- JZOJ 5246. 【NOIP2017模拟8.8A组】Trip(trip)
5246. [NOIP2017模拟8.8A组]Trip(trip) (File IO): input:trip.in output:trip.out Time Limits: 1500 ms Memo ...
- JZOJ 5236. 【NOIP2017模拟8.7A组】利普希茨
5236. [NOIP2017模拟8.7A组]利普希茨 (File IO): input:lipschitz.in output:lipschitz.out Time Limits: 1000 ms ...
- JZOJ 【NOIP2017提高A组模拟9.14】捕老鼠
JZOJ [NOIP2017提高A组模拟9.14]捕老鼠 题目 Description 为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄里的仓库灭灭鼠.于是,猫被农夫约派去捕 ...
- JZOJ 5257. 小X的佛光 (Standard IO)
5257. 小X的佛光 (Standard IO) Time Limits: 2000 ms Memory Limits: 524288 KB Description Input Output Sam ...
- JZOJ 5235. 【NOIP2017模拟8.7A组】好的排列
5235. [NOIP2017模拟8.7A组]好的排列 (File IO): input:permutation.in output:permutation.out Time Limits: 1000 ...
- JZOJ 5230. 【NOIP2017模拟A组模拟8.5】队伍统计
5230. [NOIP2017模拟A组模拟8.5]队伍统计 (File IO): input:count.in output:count.out Time Limits: 1500 ms Memory ...
随机推荐
- JavaScript-CasperJs使用教程
如果是类似12306这种网站的话, 必须使用--ssl-protocol=any --ignore-ssl-errors=true选项, 例如 casperjs --ssl-protocol=any ...
- MBProgressHUD 设置透明背景
MBProgressHUD 默认使用MBProgressHUDBackgroundStyleBlur 类型 MBProgressHUDBackgroundStyleBlur使用了毛玻璃效果 ,我们要把 ...
- Hadoop文件解压缩
Class org.apache.hadoop.io.compress .CompressionCodecFactory A factory that will find the correct co ...
- 安装VS2010 SP1后,再安装mvc3
安装VS2010 SP1后,再安装mvc3会报错,估计原因是此安装包会安装VS的补丁,而sp1的补丁版本高过此安装包的. AspNetMVC3ToolsUpdateSetup.exe 解决办法: 运行 ...
- Go快速入门
整理一些Go最基本的语法,旨在快速入门. 最简单的hello world package main import "fmt" func main() { fmt.Println(& ...
- iOS网络访问之使用AFNetworking
AFNetworking是IOS上常用的第三方网络访问库,我们可以在github上下载它,同时github上有它详细的使用说明,最新的AFNetworing2.0与1.0有很大的变化,这里仅对2.0常 ...
- 【转】Cocos2d-x 3.1.1 学习日志6--30分钟了解C++11新特性
[转]Cocos2d-x 3.1.1 学习日志6--30分钟了解C++11新特性 Cocos2d-x 3.1.1 学习日志6--30分钟了解C++11新特性
- Window 窗口类
窗口类 WNDCLASS 总结 总结为下面的几个问题: . 什么是窗口类 . 窗口类的三种类型 . 窗口类各字段含义 . 窗口类的注册和注销 . 如何使用窗口类,子类化.超类化是什么 下面分别描述: ...
- 去掉IntelliJ IDEA代码编辑区域的竖线
(网络配图) 作为从事编程或者测试工作的人来说,尤其是有强迫症的,看着非常痛苦,我们来看看怎么去掉 在 Settings-> Editor-> General-> Appearanc ...
- scala读写文件
def main(args: Array[String]): Unit = { //1 read for( i<- Source.fromFile("test.dat").g ...