一道傻逼链剖我TM总共差不多写了一小时,调了将近一天!!!!!!

题目传送门:http://www.spoj.com/problems/DISQUERY/

嗯,偷偷递小广告:SPOJ是个挺好的OJ (因为可以交BF和WhiteSpace代码)
从里面见到了很多没见过的语言(尽管根据提交记录来讲好像也没什么人用2333)

然后再%%%一下评论区里1A的dalao… 我真是调跪了…(我还是太弱了orz)

题目大意:
给一棵树,每次询问x->y之间的路径上边权最大和最小的边.

心路历程:
这TM不就一道傻逼链剖么…
且慢,好像是边权? 那下放到点权不就完了么= =
(我真的以为自己是对的)
然后就用了半小时打了个链剖板子,然后……不出所料,死递归了…
然后就各种调试(由于DEV-C++显示莫名爆炸,所以用的VS2015调试,非常爽啊),发现自己max min都能打反也是人才…
然后发现下放之后1号节点(根)不好处理啊,加了个特判,乱搞了一波,就过了样例2啊…
然后样例1带进去怎么做都不对啊,以为是自己代码的问题,又debug然后各种乱搞,但是怎么折腾都不对,再一步一步调,发现一切都在按照自己想象的进行?

于是打开神器mspaint画了个图,发现下放点权不行啊….
于是以为自己写了半天的代码算是废了,但是咋做呢?
就去问了问dalao(感谢这位不愿透露姓名(其实是我不想打TA名字2333)的dalao)
然后dalao告诉我连x->y边的时候可以拆成x->z->y的两条边啊,然后把边权放在z就可以了~~
就茅塞顿开了.
回头又改了改代码然后又死递归了,发现自己的线段树操作都是1,1,n所以会越界,所以就动态改了n(懒得改线段树的代码,好容易才debug的没啥问题),结果有些地方的n又不行所以开了两个变量…
最后终于过了所有的样例…
然后交上去RE了,因为加虚拟点的话点数会翻倍…只开N的数组是不行的….
就把N改成了200000就A了(并没看内存限制,真是幸运呢~)

嗯 综上所述,这题就是一道傻逼链剖但是我更傻逼到不会处理所以就调了这么长时间= =
讲个笑话我第一遍打的链剖板子就是对的但是由于过不了样例我还怀疑了好久正确性并debug了不知道多少遍orz….


代码:

#include <cstdio>
const int N = 200010;
const int F = ~0U >> 1;
inline int max(const int &a, const int &b) {
if (a < b) return b; return a;
}
inline int min(const int &a, const int &b) {
if (a < b) return a; return b;
}
inline int getnum() {
int a = 0; char c = getchar(); bool f = 0;
for (; (c<'0' || c>'9') && c != '-'; c = getchar());
if (c == '0') c = getchar(), f = 1;
for (; c >= '0'&&c <= '9'; c = getchar()) a = (a << 1) + (a << 3) + c - '0';
if (f) return -a; return a;
} int w[N], n, m;
int fa[N], d[N], sz[N], ez[N];
int top[N], pos[N], rank[N], ti; struct edge {
int to, next;
}e[N << 1]; int v[N], tot;
void buildedge(int x, int y) {
e[++tot].to = y; e[tot].next = v[x]; v[x] = tot;
e[++tot].to = x; e[tot].next = v[y]; v[y] = tot;
} struct node {
int bn, sn;
}t[N << 2]; void dfs1(int x) {
sz[x] = 1; ez[x] = x;
for (int i = v[x]; i; i = e[i].next) {
int y = e[i].to;
if (!d[y]) {
d[y] = d[x] + 1;
dfs1(y);
fa[y] = x;
sz[x] += sz[y];
if (ez[x] == x || sz[y] > sz[ez[x]])
ez[x] = y;
}
}
} void dfs2(int x, int tp) {
pos[++ti] = x; rank[x] = ti; top[x] = tp;
if (ez[x] != x) dfs2(ez[x], tp);
for (int i = v[x]; i; i = e[i].next) {
int y = e[i].to;
if (d[y] == d[x] + 1 && y != ez[x])
dfs2(y, y);
}
} void update(int x) {
t[x].sn = min(t[x << 1].sn, t[x << 1 | 1].sn);
t[x].bn = max(t[x << 1].bn, t[x << 1 | 1].bn);
} void build(int x, int l, int r) {
if (l == r) {
int id = pos[++ti];
if (id <= m) t[x].sn = F, t[x].bn = -F;
else t[x].sn = t[x].bn = w[id];
//唯一要交代的可能就是这样的处理了,为了防止实际节点的点权影响到结果(比如设为0可能会影响到最小值),我们把实际节点的最大值设为无穷小,最小值设为无穷大即可...
return;
}
int mid = (l + r) >> 1;
build(x << 1, l, mid);
build(x << 1 | 1, mid + 1, r);
update(x);
} int query_min(int x, int l, int r, int L, int R) {
if (L <= l&&r <= R) return t[x].sn;
int mid = (l + r) >> 1, ans = F;
if (L <= mid) ans = min(ans, query_min(x << 1, l, mid, L, R));
if (R > mid) ans = min(ans, query_min(x << 1 | 1, mid + 1, r, L, R));
return ans;
} int query_max(int x, int l, int r, int L, int R) {
if (L <= l&&r <= R) return t[x].bn;
int mid = (l + r) >> 1, ans = -F;
if (L <= mid) ans = max(ans, query_max(x << 1, l, mid, L, R));
if (R > mid) ans = max(ans, query_max(x << 1 | 1, mid + 1, r, L, R));
return ans;
} void query(int x, int y, int &mins, int &maxs) {
int bs = -F, ss = F;
while (top[x] != top[y]) {
if (d[top[x]] > d[top[y]]) {
bs = max(bs, query_max(1, 1, n, rank[top[x]], rank[x]));
ss = min(ss, query_min(1, 1, n, rank[top[x]], rank[x]));
x = fa[top[x]];
}
else {
bs = max(bs, query_max(1, 1, n, rank[top[y]], rank[y]));
ss = min(ss, query_min(1, 1, n, rank[top[y]], rank[y]));
y = fa[top[y]];
}
}
if (d[x] < d[y]) {
bs = max(bs, query_max(1, 1, n, rank[x], rank[y]));
ss = min(ss, query_min(1, 1, n, rank[x], rank[y]));
}
else{
bs = max(bs, query_max(1, 1, n, rank[y], rank[x]));
ss = min(ss, query_min(1, 1, n, rank[y], rank[x]));
}
mins = ss; maxs = bs;
} int main() {
m = getnum(); n = m;
for (int i = 1; i < m; i++) {
int a = getnum(), b = getnum(), c = getnum();
buildedge(a, ++n); buildedge(n, b); w[n] = c;
}
d[1] = 1; dfs1(1); dfs2(1, 1); ti = 0; build(1, 1, n); int k = getnum();
for (int i = 1; i <= k; i++) {
int a = getnum(), b = getnum(), ans1, ans2;
query(a, b, ans1, ans2);
printf("%d %d\n", ans1, ans2);
}
}

反正就这样吧…

最新文章

  1. Java-简陋的图书管理
  2. Vim-Vundle-plugins-scripts
  3. MSMQ消息队列
  4. Multithreading annd Grand Central Dispatch on ios for Beginners Tutorial-多线程和GCD的入门教程
  5. 第三百六十天 how can I 坚持
  6. android 利用数字证书对程序签名
  7. Android Studio-ApplicationId 与 PackageName
  8. c语言,const被绕过
  9. spark 1.6 完全分布式平台搭建
  10. Unity3D外包 团队更新一下UE4和Unity3D案例
  11. Oracle基础--创建临时表空间/表空间/创建用户/授权
  12. asp 读cookie 下划线 丢失
  13. mysqldump进行复制数据导出导入时的问题
  14. python中的if判断语句
  15. CentOS7下安装caffe(包括ffmpeg\boost\opencv)
  16. 机器学习结果加ID插入数据库源码
  17. 数据分析--降维--LDA和PCA
  18. 使用httpClient处理get请求或post请求
  19. OpenGL学习笔记(4) GLM库的使用
  20. 【Anroid】9.1 ListView相关类及其适配器

热门文章

  1. 在vs2010下编译boost
  2. (转)python常用模块(模块和包的解释,time模块,sys模块,random模块,os模块,json和pickle序列化模块)
  3. 16-Ubuntu-文件和目录命令-切换目录-cd
  4. Winform 窗体闪烁 &amp; 任务栏提示
  5. WebService接口测试
  6. idea中项目发布到svn服务器
  7. 用PS制作APP的界面图片
  8. OC开发系列-类与对象
  9. DataList做一个相册,并可以上传图片
  10. mysql的双主模式