【NOIP2016提高A组集训第5场11.2】行走
来源:互联网 发布:mysql 窗口函数 over 编辑:程序博客网 时间:2024/05/16 11:32
Input
第一行两个整数n和q表示点个数和询问与操作个数
接下来n-1行每行三个整数u,v,c表示u与v之间有一条边权为c的边
接下来q行每行第一个数type
如果type=1那么接下来三个数x,y,v表示一组询问
如果type=2那么接下来两个数p,c表示一组操作
Output
对于每组询问输出一个数表示最后的答案
Sample Input
样例输入1
6 6
1 2 1
1 3 7
1 4 4
2 5 5
2 6 2
1 4 6 17
2 3 2
1 4 6 17
1 5 5 20
2 4 1
1 5 1 3
样例输入2
5 4
1 2 7
1 3 3
3 4 2
3 5 5
1 4 2 100
1 5 4 1
2 2 2
1 1 3 4
Sample Output
样例输出1
2
4
20
3
样例输出2
2
0
2
Data Constraint
对于70%的数据保证 n <= 1000
对于100%的数据保证 n,q <=
保证每次修改后的边权小于等于原来的边权且不会小于1
题解
首先我们发现如果答案不为1那么路径上最多只有60个值不为1的边(否则最后的答案小于等于1)。那么我们可以对权值等于1的边并查集,然后对于每一对询问做一次lca,然后往上跑就可以了
贴代码
var fa,deep:array[0..100005]of longint; a,f,p:array[0..200005,1..3]of int64; b:array[0..100005,1..2]of longint; bz:array[0..100005]of boolean; ff:array[0..100005,0..18]of longint; cc:array[0..20]of longint; i,j,k,l,n,q,x,y,t1,t2,x1,y1:longint; z:int64;procedure qsort(l,r:longint);var i,j,mid:longint;begin i:=l; j:=r; mid:=a[(i+j) div 2,1]; repeat while a[i,1]<mid do inc(i); while a[j,1]>mid do dec(j); if i<=j then begin a[0]:=a[i]; a[i]:=a[j]; a[j]:=a[0]; inc(i); dec(j); end; until i>j; if i<r then qsort(i,r); if l<j then qsort(l,j);end;procedure star;begin b[a[1,1],1]:=1; for i:=2 to 2*n-2 do if a[i,1]<>a[i-1,1] then begin b[a[i-1,1],2]:=i-1; b[a[i,1],1]:=i; end; b[a[2*n-2,1],2]:=2*n-2;end;procedure make_f(x:longint);var i:longint;begin bz[x]:=true; for i:=b[x,1] to b[x,2] do if (i<>0) and (bz[a[i,2]]=false) then begin f[a[i,2],1]:=x; f[a[i,2],2]:=a[i,3]; deep[a[i,2]]:=deep[x]+1; make_f(a[i,2]); end;end;function getfather(x:longint):longint;begin if fa[x]=x then exit(x) else fa[x]:=getfather(fa[x]); exit(fa[x]);end;procedure make_ff;var i,j:longint;begin for j:=1 to 17 do for i:=2 to n do ff[i,j]:=ff[ff[i,j-1],j-1];end;begin assign(input,'walk.in'); reset(input); assign(output,'walk.out'); rewrite(output); readln(n,q); for i:=1 to n-1 do begin readln(a[i,1],a[i,2],a[i,3]); a[i+n-1,1]:=a[i,2]; a[i+n-1,2]:=a[i,1]; a[i+n-1,3]:=a[i,3]; end; p:=a; qsort(1,2*n-2); star; deep[1]:=1; make_f(1); for i:=1 to n do fa[i]:=i; for i:=2 to n do if f[i,2]=1 then begin x:=getfather(f[i,1]); y:=getfather(i); if x<>y then fa[y]:=x; end; for i:=2 to n do ff[i,0]:=f[i,1]; cc[0]:=1; for i:=1 to 17 do cc[i]:=cc[i-1]*2; make_ff; for i:=1 to q do begin read(x); if x=1 then begin readln(x,y,z); x1:=x; y1:=y; if deep[x]<deep[y] then begin t1:=x; x:=y; y:=t1; end; t1:=deep[x]-deep[y]; t2:=0; while t1>0 do begin if t1 mod 2=1 then x:=ff[x,t2]; inc(t2); t1:=t1 div 2; end; t1:=deep[x]; for j:=17 downto 0 do if ff[x,j]<>ff[y,j] then begin x:=ff[x,j]; y:=ff[y,j]; t1:=t1-cc[j]; end; if x<>y then dec(t1); x:=x1; while (deep[x]>t1) and (z>0) do begin if f[x,2]=1 then begin x:=getfather(f[x,1]); if deep[x]<=t1 then break; end else begin z:=z div f[x,2]; x:=f[x,1]; end; end; x:=y1; while (deep[x]>t1) and (z>0) do begin if f[x,2]=1 then begin x:=getfather(f[x,1]); if deep[x]<=t1 then break; end else begin z:=z div f[x,2]; x:=f[x,1]; end; end; writeln(z); end else begin readln(x,y); if f[p[x,2],1]=p[x,1] then begin f[p[x,2],2]:=y; t1:=p[x,2]; t2:=p[x,1]; end else begin f[p[x,1],2]:=y; t1:=p[x,1]; t2:=p[x,2]; end; if y=1 then fa[t1]:=t2; end; end; close(input); close(output);end.
0 0
- 【NOIP2016提高A组集训第5场11.2】行走
- 【JZOJ4846】【NOIP2016提高A组集训第5场11.2】行走
- JZOJ4846【NOIP2016提高A组集训第5场11.2】行走
- 【NOIP2016提高A组集训第5场11.2】夕阳
- 【NOIP2016提高A组集训第5场11.2】寻找
- 【JZOJ4845】【NOIP2016提高A组集训第5场11.2】寻找
- 4845. 【NOIP2016提高A组集训第5场11.2】寻找
- 【JZOJ4847】【NOIP2016提高A组集训第5场11.2】夕阳
- JZOJ4847【NOIP2016提高A组集训第5场11.2】夕阳
- JZOJ 4845 【NOIP2016提高A组集训第5场11.2】寻找
- 4847. 【NOIP2016提高A组集训第5场11.2】夕阳
- 【NOIP2016提高A组集训第3场10.31】方程式
- 方程式 【NOIP2016提高A组集训第3场10.31】
- 【NOIP2016提高A组集训第7场11.4】连锁店
- NOIP2016提高A组集训第8场11.5 总结
- 【NOIP2016提高A组集训第9场11.7】Simple
- NOIP2016提高A组集训第8场11.5总结
- 【NOIP2016提高A组集训第9场11.7】平均数
- Java:list.remove()放入Integer值返回false
- Vivado Hls 设计流程总结
- 字符编码详解
- PAT--1109. Group Photo
- POJ 1007 DNA Sorting
- 【NOIP2016提高A组集训第5场11.2】行走
- 初学者VS常用快捷键
- 一篇文章教你理解重载与重写
- 谈养生
- java异常
- 2016.11.07
- 自定义封装Volley的请求集合
- running and debugging xv6
- View动画的XML与Java代码实现的两种方式,交叉着用