一道傻逼链剖我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);
}
}

反正就这样吧…

【学术篇】SPOJ-DISQUERY的更多相关文章

  1. 【学术篇】SPOJ GEN Text Generator AC自动机+矩阵快速幂

    还有5天省选才开始点字符串这棵技能树是不是太晚了点... ~题目の传送门~ AC自动机不想讲了QAQ.其实很久以前是学过然后打过板子的, 但也仅限于打过板子了~ 之前莫名其妙学了一个指针版的但是好像不 ...

  2. 【学术篇】SPOJ FTOUR2 点分治

    淀粉质入门第一道 (现在个人认为spoj比bzoj要好_(:з」∠)_ 关于点分治的话推荐去看一看漆子超的论文>>>这里这里<<< 之前一直试图入点分治坑, 但是因 ...

  3. 【学术篇】SPOJ QTREE 树链剖分

    发现链剖这东西好久不写想一遍写对是有难度的.. 果然是熟能生巧吧.. WC的dalao们都回来了 然后就用WC的毒瘤题荼毒了我们一波, 本来想打个T1 44分暴力 然后好像是特判写挂了还是怎么的就只能 ...

  4. 【学术篇】SPOJ COT 树上主席树

    这是学完主席树去写的第二道题_(:з」∠)_ 之前用树上莫队水过了COT2... 其实COT也可以用树上莫队水过去不过好像复杂度要带个log还是怎么样可能会被卡常数.. 那就orz主席吧.... 写了 ...

  5. 【学术篇】一些水的不行的dp

    最近做了几道非常水非常水的dp...... 之后刷的一些水dp也会写在这里...... 此篇题目难度不递增!!! Emmmm....... 1.luogu1043数字游戏 以前看过这个题几遍,没做这个 ...

  6. 【学术篇】51nod 1238 最小公倍数之和

    这是一道杜教筛的入(du)门(liu)题目... 题目大意 求 \[ \sum_{i=1}^n\sum_{j=1}^nlcm(i,j) \] 一看就是辣鸡反演一类的题目, 那就化式子呗.. \[ \s ...

  7. 【学术篇】luogu2184贪婪大陆

    题目在这里哦, 戳一下就可以了~ 题目大意: 支持两种操作,区间添加一种新元素,查询区间颜色种数.. 题目标签是线段树啊,我也本来想写一个线段树,后来写不出来……(我太弱了orz) 然后就草率地看了看 ...

  8. 【学术篇】oj.jzxx.net2701 无根树

    这是一道来自OIerBBS的题目.. 原帖地址:http://www.oierbbs.com/forum.php?mod=viewthread&tid=512?fromuid=71 (似乎是个 ...

  9. SPOJ DISQUERY LCA + 倍增

    裸题,如此之水- Code: #include<cstdio> #include<algorithm> using namespace std; const int maxn ...

随机推荐

  1. 码云挂了,无法访问gitee

    解决方式1.修改dns为114.114.114.114 2.hosts文件添加212.64.62.174   gitee.com

  2. P1910 L国的战斗之间谍

    P1910 L国的战斗之间谍 题目背景 L国即将与I国发动战争!! 题目描述 俗话说的好:“知己知彼,百战不殆”.L国的指挥官想派出间谍前往I国,于是,选人工作就落到了你身上. 你现在有N个人选,每个 ...

  3. POJ 3667 线段树区间合并裸题

    题意:给一个n和m,表示n个房间,m次操作,操作类型有2种,一种把求连续未租出的房间数有d个的最小的最左边的房间号,另一个操作时把从x到x+d-1的房间号收回. 建立线段树,值为1表示未租出,0为租出 ...

  4. USACO2012 Haybale stacking /// 区间表示法 oj21556

    题目大意:N个方块 标号1~N  K个操作 操作a b 表示标号a~b区间每位多加一个方块 Input * Line 1: Two space-separated integers, N  K. * ...

  5. Jmeter----函数助手参数化

    要填写开始日期和结束日期和赋值的变量名

  6. Logstash2.3.4趟坑之集成Redis哨兵模式

    最新在使用Lostash2.3.4收集数据的时候,在读取redis数据的时候,报了如下的一个异常: 异常如下 Pipeline aborted due to error {:exception=> ...

  7. excel 导数据

    参考: ="insert tsilverinfo(ss_id,memo,ss_weight,ts_id,ss_type,ModelPosX,ss_stoneW,ss_stoneWU) val ...

  8. Java带头节点单链表的增删合并以及是否有环

    带头节点单链表 1.优势: 1)当链表为空时,指针指向头结点,不会发生null指针异常 2)方便特殊操作(删除第一个有效节点或者插入一个节点在表头) 3)单链表加上头结点之后,无论单链表是否为空,头指 ...

  9. thinkphp 正则路由

    正则路由也就是采用正则表达式定义路由的一种方式,依靠强大的正则表达式,能够定义更灵活的路由规则. 路由表达式支持的正则定义必须以“/”开头,否则就视为规则表达式.也就是说如果采用: '#^blog\/ ...

  10. for双重循环中的结构分离(语法结构问题)

    //增加搜索列表 function addSearchList(){ $.get("/mall/h5_get_search_list.html","",func ...