spoj题面

Time limit 433 ms //spoj的时限都那么奇怪

Memory limit 1572864 kB //1.5个G,疯了

Code length Limit 15000 B

OS Linux

Language limit All except: ERL JS-RHINO NODEJS PERL6 VB.NET

Source Special thanks to Ivan Krasilnikov for his alternative solution

Author Thanh-Vy Hua

吐槽

期中考第二个能A的题,结果写了半个小时,调了一个半小时……纪念一下第二道被多组Case读入害死的题目……这题是把下一个case的前两个数读进来了,那一次是这次的case没读完就进入下一个case了,这才过了两个星期啊……下次测这种样例就该把样例多复制几遍……

顺便吐槽,这是啥数据啊……一步一步地向上暴力跳都能A,亏我还跳重链……而且case之间加空行这个要求它不会判,加不加空行都是AC

解题思路

我一看见这题就没多想,直接上树链剖分,结果写完反应过来杀鸡用牛刀,这题dfs预处理一遍,倍增跳树并统计结果是更优的办法,代码可以短不少。

树链剖分处理\(KTH\)操作是利用了一个性质:一条重链上的节点新id,从上到下是连续的,所以跳链的时候如果发现跳过了目标\(k\),那么就直接使用这条重链两端的新\(id\)计算出目标\(k\)的\(id\),然后转换成原来的的编号即可。另外,由于这题路径有了方向,所以跳链的时候不能像平时那样std::swap(u,v),而是要判断应该跳u还是跳v,然后分情况写。

源代码

#include<stdio.h>
#include<string.h>
#include<algorithm>
int T;
int n; struct Edge{
int nxt,to,w;
}e[200010];
int head[100010],cnt;
void add(int u,int v,int w)
{
e[cnt]={head[u],v,w};
head[u]=cnt++;
e[cnt]={head[v],u,w};
head[v]=cnt++;
} struct Tree{
int fa,dep,w,sz,wson;
int top,id;
}t[100010];
void dfs1(int fa,int u,int w)
{
t[u].fa=fa;
t[u].dep=t[fa].dep+1;
t[u].w=w;
t[u].sz=1;
int maxn=0;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==fa) continue;
dfs1(u,v,e[i].w);
int temp=t[v].sz;
t[u].sz+=temp;
if(temp>maxn)
{
maxn=temp;
t[u].wson=v;
}
}
}
int id=1;
int mp[100010];//用新id查询老id
long long a[100010];
void dfs2(int u,int top)
{
t[u].top=top;
t[u].id=id;
a[id]=t[u].w;
mp[id]=u;
id++;
if(t[u].sz==1) return;
dfs2(t[u].wson,top);
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==t[u].fa||v==t[u].wson) continue;
dfs2(v,v);
}
} long long sum[400010];//线段树维护区间和
void build(int x,int l,int r)
{
if(l==r)
{
sum[x]=a[l];
return;
}
int mid=l+r>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
sum[x]=sum[x<<1]+sum[x<<1|1];
}
long long quesum(int x,int l,int r,int ql,int qr)
{
if(qr<ql) return 0;
if(ql<=l&&r<=qr) return sum[x];
int mid=l+r>>1;
long long ans=0;
if(ql<=mid) ans+=quesum(x<<1,l,mid,ql,qr);
if(qr>mid) ans+=quesum(x<<1|1,mid+1,r,ql,qr);
return ans;
} long long dist(int u,int v)
{
long long ans=0;
while(t[u].top!=t[v].top)
{
if(t[t[u].top].dep<t[t[v].top].dep) std::swap(u,v);
ans+=quesum(1,1,n,t[t[u].top].id,t[u].id);
u=t[t[u].top].fa;
}
if(t[u].id>t[v].id) std::swap(u,v);
ans+=quesum(1,1,n,t[u].id+1,t[v].id);
return ans;
} int kth(int ss,int tt,int k)//要区分起点和终点
{
int num=0;
int u=ss,v=tt;//先跳一遍找到总的点数
while(t[u].top!=t[v].top)
{
if(t[t[u].top].dep<t[t[v].top].dep) std::swap(u,v);
num+=t[u].id-t[t[u].top].id+1;//这条重链
u=t[t[u].top].fa;
}
if(t[u].id>t[v].id) std::swap(u,v);
num+=t[v].id-t[u].id+1;
while(t[ss].top!=t[tt].top)//跳链找答案
{
if(t[t[ss].top].dep<t[t[tt].top].dep)//跳tt点
{
int temp=t[tt].id-t[t[tt].top].id+1;//重链长度
if(num-temp<k)//跳过了
{
return mp[t[tt].id-(num-k)];
}
else//还在上方,num减少
{
num-=temp;
tt=t[t[tt].top].fa;
}
}
else//跳ss点
{
int temp=t[ss].id-t[t[ss].top].id+1;
if(k<=temp)//找到了
{
return mp[t[ss].id-k+1];
}
else//还在上方
{
k-=temp;
num-=temp;
ss=t[t[ss].top].fa;
}
}
}
//跳到同一条链上了。
if(t[ss].dep<t[tt].dep)
return mp[t[ss].id+k-1];
else
return mp[t[ss].id-k+1];
} int main()
{
//freopen("test.in","r",stdin);
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
memset(head,0,sizeof(int)*(n+2));
cnt=id=1;
for(int i=1,u,v,w;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
dfs1(0,1,0);
dfs2(1,1);
build(1,1,n);
while(1)
{
char opt[10];
int u,v,k;
scanf("%s",opt);//开始我写了个%s%d%d,opt,&u,&v……
if(opt[1]=='I')
{
scanf("%d%d",&u,&v);
printf("%lld\n",dist(u,v));
}
else if(opt[1]=='T')
{
scanf("%d%d%d",&u,&v,&k);
printf("%d\n",kth(u,v,k));
}
else break;
}
puts("");//空行加不加都可以A
}
return 0;
}

SPOJ 913 Query on a tree II的更多相关文章

  1. spoj 913 Query on a tree II (倍增lca)

    Query on a tree II You are given a tree (an undirected acyclic connected graph) with N nodes, and ed ...

  2. QTREE2 spoj 913. Query on a tree II 经典的倍增思想

    QTREE2 经典的倍增思想 题目: 给出一棵树,求: 1.两点之间距离. 2.从节点x到节点y最短路径上第k个节点的编号. 分析: 第一问的话,随便以一个节点为根,求得其他节点到根的距离,然后对于每 ...

  3. SPOJ QTREE2 Query on a tree II

    传送门 倍增水题…… 本来还想用LCT做的……然后发现根本不需要 //minamoto #include<bits/stdc++.h> using namespace std; #defi ...

  4. 【SPOJ】Count On A Tree II(树上莫队)

    [SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...

  5. 【BZOJ2589】 Spoj 10707 Count on a tree II

    BZOJ2589 Spoj 10707 Count on a tree II Solution 吐槽:这道题目简直...丧心病狂 如果没有强制在线不就是树上莫队入门题? 如果加了强制在线怎么做? 考虑 ...

  6. LCA SP913 QTREE2 - Query on a tree II

    SP913 QTREE2 - Query on a tree II 给定一棵n个点的树,边具有边权.要求作以下操作: DIST a b 询问点a至点b路径上的边权之和 KTH a b k 询问点a至点 ...

  7. SPOJ COT2 - Count on a tree II(LCA+离散化+树上莫队)

    COT2 - Count on a tree II #tree You are given a tree with N nodes. The tree nodes are numbered from  ...

  8. SPOJ 375. Query on a tree (树链剖分)

    Query on a tree Time Limit: 5000ms Memory Limit: 262144KB   This problem will be judged on SPOJ. Ori ...

  9. SPOJ QTREE Query on a tree 树链剖分+线段树

    题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...

随机推荐

  1. Book - 《Python编程:从入门到实践》

    Tag:看<Python编程:从入门到实践>学习笔记 数据类型相关: 字符串str 改变大小写(临时):title首字母大写,upper全大写,lower全小写 删除空白(临时):rstr ...

  2. hbase 查看hfile文件

    emp表数据结构 hbase(main):098:0> scan 'emp' ROW COLUMN+CELL row1 column=mycf:depart, timestamp=1555846 ...

  3. 洛谷 P1306 斐波那契公约数 题解

    题面 结论:gcd(F[n],F[m])=F[gcd(n,m)]; F[n]=a和F[n+1]=b F[n+2]=a+b,F[n+3]=a+2b,…F[m]=F[m?n?1]a+F[m?n]b F[n ...

  4. fiddler 不能抓包解决

    早上使用金山毒霸扫描了一遍电脑,然后打开fiddler后,出现了一个提示(当时没有注意看),直接点了确定,导致结果是不能抓包了,百度了很多方法,最后直接卸载金山毒霸,然后将防火墙还原为默认设置(风险不 ...

  5. HNUST-1047 二叉树的表示

    1047: 二叉树的表示 时间限制: 1 Sec  内存限制: 128 MB提交: 4  解决: 4[提交][状态][讨论版] 题目描述 ​DJ非常痴迷于数据结构,二叉树是他最喜欢的结构模型.这种每个 ...

  6. Bootstrap中DropDown插件显示下拉列表,点击下拉列表区域,不会再自动关闭。

    目标: Bootstrap中DropDown插件显示下拉列表,点击下拉列表区域,不会再自动关闭. 参考:http://v3.bootcss.com/javascript/#dropdowns    / ...

  7. java中常见的异常种类

    Java常见的异常种类 ------------------------------------------------------------------------------- java Exc ...

  8. the server responsed width a status of 404 (Not Found)

    最近使用VS code写代码,使用Beautify插件格式化代码后,报以下错误: 反复查看代码,初始感觉没什么问题,有点懵.. 随着时间的推移,后来果然发现问题所在: 在加载模块的地方,多出了个空格( ...

  9. vue+hbuilder 打包成移动app

    查看了很多网上写的改来改去都在手机上运行不起来,运行起来又是白屏:最后放弃,自己结合文档搞吧! 1. 项目目录下的config文件夹里的index.js文件中,将build对象下的assetsPubl ...

  10. python中的正则表达式的使用

    一.正则表达式简介 正则表达式的官方文档:https://www.runoob.com/regexp/regexp-tutorial.html 正则表达式:又称正规表示式.正规表示法.正规表达式.规则 ...