bzoj3551 3545
2015-06-20 17:01
288 查看
我直接来讲在线好了
这是一个很巧妙的方法,把边作为一个点
做一遍最小生成树,当加如一条边时,我们把这条边两点x,y的并查集的根i,j的父亲都设为这条边代表的点k,由k向i,j连边
这样我们就构建出一棵树,这棵树的叶子都是原来节点
且每棵子树都是在子树根所代表的边的限制下的最小连通块
这样我们就可以通过dfs序(只用对叶子标号)+主席树来维护k大了并通过倍增找到限制
这两题都是一副卡pascal过不了的样子……QAQ
另外网上的一些标称(bzoj3551)似乎没有考虑一个点没有边可走,但询问k=1的情况,可以加数据cha
View Code
这是一个很巧妙的方法,把边作为一个点
做一遍最小生成树,当加如一条边时,我们把这条边两点x,y的并查集的根i,j的父亲都设为这条边代表的点k,由k向i,j连边
这样我们就构建出一棵树,这棵树的叶子都是原来节点
且每棵子树都是在子树根所代表的边的限制下的最小连通块
这样我们就可以通过dfs序(只用对叶子标号)+主席树来维护k大了并通过倍增找到限制
这两题都是一副卡pascal过不了的样子……QAQ
另外网上的一些标称(bzoj3551)似乎没有考虑一个点没有边可走,但询问k=1的情况,可以加数据cha
type node=record po,next:longint; end; way=record x,y,z:longint; end; point=record l,r,s:longint; end; var e:array[0..400010] of node; w:array[0..500010] of way; v:array[0..400010] of boolean; anc:array[0..200010,0..20] of longint; d,l,r,p,fa,c,a,b,h:array[0..200010] of longint; tree:array[0..200010*20] of point; num,j,s,size,i,len,t,n,m,q,x,y,ans,k:longint; function min(a,b:longint):longint; begin if a>b then exit(b) else exit(a); end; function max(a,b:longint):longint; begin if a>b then exit(a) else exit(b); end; function getf(x:longint):longint; begin if fa[x]<>x then fa[x]:=getf(fa[x]); exit(fa[x]); end; procedure swap(var a,b:longint); var c:longint; begin c:=a; a:=b; b:=c; end; procedure sort(l,r:longint); var i,j,x:longint; begin i:=l; j:=r; x:=a[(l+r) shr 1]; repeat while a[i]<x do inc(i); while x<a[j] do dec(j); if i<=j then begin swap(a[i],a[j]); swap(b[i],b[j]); inc(i); dec(j); end; until i>j; if l<j then sort(l,j); if i<r then sort(i,r); end; procedure qsort(l,r:longint); var i,j,x:longint; y:way; begin i:=l; j:=r; x:=w[(l+r) shr 1].z; repeat while w[i].z<x do inc(i); while x<w[j].z do dec(j); if i<=j then begin y:=w[i]; w[i]:=w[j]; w[j]:=y; inc(i); dec(j); end; until i>j; if l<j then qsort(l,j); if i<r then qsort(i,r); end; procedure dfs(x:longint); var i,y:longint; begin v[x]:=true; if x<=n then begin inc(num); b[num]:=x; l[x]:=num; r[x]:=num; exit; end; i:=p[x]; l[x]:=n; r[x]:=0; while i<>0 do begin y:=e[i].po; anc[y,0]:=x; dfs(y); l[x]:=min(l[x],l[y]); r[x]:=max(r[x],r[y]); i:=e[i].next; end; end; function find(x,y:longint):longint; var i:longint; begin for i:=size downto 0 do if a[anc[x,i]]<=y then x:=anc[x,i]; exit(x); end; function build(l,r:longint):longint; var m,q:longint; begin inc(t); q:=t; if l<>r then begin m:=(l+r) shr 1; tree[q].l:=build(l,m); tree[q].r:=build(m+1,r); end; exit(q); end; function add(l,r,last,x:longint):longint; var m,q:longint; begin inc(t); q:=t; if l=r then tree[q].s:=tree[last].s+1 else begin m:=(l+r) shr 1; if x<=m then begin tree[q].r:=tree[last].r; tree[q].l:=add(l,m,tree[last].l,x); end else begin tree[q].l:=tree[last].l; tree[q].r:=add(m+1,r,tree[last].r,x); end; tree[q].s:=tree[tree[q].l].s+tree[tree[q].r].s; end; exit(q); end; function ask(l,r,x,y,k:longint):longint; var m,s:longint; begin if l=r then exit(c[l]) else begin m:=(l+r) shr 1; s:=tree[tree[y].r].s-tree[tree[x].r].s; if s>=k then exit(ask(m+1,r,tree[x].r,tree[y].r,k)) else exit(ask(l,m,tree[x].l,tree[y].l,k-s)); end; end; procedure ins(x,y:longint); begin inc(len); e[len].po:=y; e[len].next:=p[x]; p[x]:=len; end; begin readln(n,m,q); for i:=1 to n do begin read(d[i]); a[i]:=d[i]; b[i]:=i; end; sort(1,n); s:=1; d[b[1]]:=1; c[1]:=a[1]; for i:=2 to n do begin if a[i]<>a[i-1] then begin inc(s); c[s]:=a[i]; end; d[b[i]]:=s; end; for i:=1 to 2*n do fa[i]:=i; for i:=1 to m do readln(w[i].x,w[i].y,w[i].z); qsort(1,m); t:=n; fillchar(a,sizeof(a),0); for i:=1 to m do begin x:=getf(w[i].x); y:=getf(w[i].y); if x<>y then begin inc(t); fa[x]:=t; fa[y]:=t; a[t]:=w[i].z; ins(t,x); ins(t,y); if t=2*n-1 then break; end; end; a[0]:=2147483647; len:=t; for i:=1 to len do if not v[i] then dfs(getf(i)); size:=trunc(ln(len)/ln(2)+0.1); for j:=1 to size do for i:=1 to len do begin x:=anc[i,j-1]; anc[i,j]:=anc[x,j-1]; end; t:=0; h[0]:=build(1,s); for i:=1 to num do h[i]:=add(1,s,h[i-1],d[b[i]]); ans:=-1; for i:=1 to q do begin readln(x,y,k); { if ans<>-1 then begin x:=x xor ans; y:=y xor ans; k:=k xor ans; end; } x:=find(x,y); if x<=n then begin if k=1 then ans:=c[d[x]] else ans:=-1; end else if tree[h[r[x]]].s-tree[h[l[x]-1]].s<k then ans:=-1 else ans:=ask(1,s,h[l[x]-1],h[r[x]],k); writeln(ans); end; end.
View Code
相关文章推荐
- mac下exe视频虚拟机播放问题
- mysql 导出表结构和表数据 mysqldump用法
- 手机屏幕适配
- 【麦可网】Cocos2d-X跨平台游戏开发学习笔记---第十课:Cocos2D-X坐标系统1
- 购买 CDRTools 2 正式版
- Intel VMCS学习总结
- shape和selector
- EasyUI +MVC实现combobox连查
- 我对汉诺塔的理解
- 学习笔记(objective-c)-协议(proto 4000 col)
- Java 实现断点续传 (HTTP)
- QT:十六进制字符串转数字整形
- c语言第二周总结-循环语句
- 最近的想法
- 【剑指offer 面试题14】调整数组顺序使奇数位于偶数前面
- Esper入门简介:三、 对Esper底层数据结构特点分析,数据的入、出
- TFS(Team Foundation Server)简介和新手入门
- Windows注册表
- netstat 显示当前网络连接的统计信息
- 在VS2010上使用C#调用非托管C++生成的DLL文件