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 ...
随机推荐
- java基础讲解05-----流程控制语句
1.条件语句 语法 : 1. if(表达式){语句块} 2. if() { }else ...
- atitit.jquery tmpl模板总结 .doc
atitit.jquery tmpl模板总结 .doc 1. atitit.动态模版解析1 1.1. Jquery.tmpl.js1 1.2. 比起anrular js方便啊.1 2. 动态模板引擎解 ...
- Sublime Text 2/3如何支持中文GBK编码(亲测实现)
Sublime Text 2/3如何支持中文GBK编码 听语音 | 浏览:17594 | 更新:2014-03-17 10:52 1 2 3 4 5 分步阅读 Sublime Text默认是只支持UT ...
- c3p0 一个数据库链接的例子
首先需要准备三个依赖包 c3p0-0.9.5.2.jar.mchange-commons-java-0.2.11.jar.mysql-connector-java-5.1.47.jar 下载链接 ht ...
- iOS之设置用户头像的圆角
1. 显示用户头像用UIImageView实现,添加默认图片后效果如下图所示,头像显示为矩形图片. 代码实现: // ViewController.m // SetUserImage // // Cr ...
- 线程的sleep()方法和yield()方法有什么区别?
1.sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会 2.yield()方法只会给相同优先级或更高优先级的线程以运行的机会 3.线程执行sleep()方法后 ...
- Oracle之批量生成数据
一.引言 由于测试程序,需要大量的数据 二.方法 1.pl/sql的Generate Data,在tool菜单中可以找到,但是我这里不能用,老是出现错误,应该是软件的原因,但是没找到解决办法,如下图: ...
- Windows/OS X下制作Mac安装U盘
Windows下制作: 方法一:(适用于OSX 10.9以前) 前期准备:一台windows电脑 UltraISO软件 Mac系统镜像dmg(这里使用Mac os x 10.8.4) 至少8GB的U盘 ...
- c++11 thread (目前我使用的ZThread库)
目前为止(2014-11-30),GCC其实已经基本上完全支持C++11的所有功能了,事实上从GCC4.7之后,就支持了-std=c++11选项,在4.7版本之前,也开始支持-std=c++0x的选项 ...
- linux-centos jdk安装
第一步:查看Linux自带的JDK是否已安装 (卸载centOS已安装的1.4) 安装好的CentOS会自带OpenJdk,用命令 java -version ,会有下面的信息: java versi ...