生活随笔
收集整理的這篇文章主要介紹了
bzoj3123
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
3123: [Sdoi2013]森林 Time Limit:?20 Sec??Memory Limit:?512 MBSubmit:?1846??Solved:?574 [Submit][Status][Discuss] Description
?
Input 第一行包含一個正整數testcase,表示當前測試數據的測試點編號。保證1≤testcase≤20。? 第二行包含三個整數N,M,T,分別表示節點數、初始邊數、操作數。第三行包含N個非負整數表示?N個節點上的權值。? ?接下來?M行,每行包含兩個整數x和?y,表示初始的時候,點x和點y?之間有一條無向邊, 接下來?T行,每行描述一個操作,格式為“Q x y k”或者“L x y?”,其含義見題目描述部分。
Output 對于每一個第一類操作,輸出一個非負整數表示答案。? ? ?
Sample Input 1 8 4 8 1 1 2 2 3 3 4 4 4 7 1 8 2 4 2 1 Q 8 7 3 Q 3 5 1 Q 10 0 0 L 5 4 L 3 2 L 0 7 Q 9 2 5 Q 6 1 6 Sample Output 2 2 1 4 2 HINT ?
對于第一個操作 Q 8 7 3,此時?lastans=0,所以真實操作為Q 8^0 7^0 3^0,也即Q 8 7 3。點8到點7的路徑上一共有5個點,其權值為4 1 1 2 4。這些權值中,第三小的為?2,輸出?2,lastans變為2。對于第二個操作 Q 3 5 1?,此時lastans=2,所以真實操作為Q 3^2 5^2 1^2?,也即Q 1 7 3。點1到點7的路徑上一共有4個點,其權值為?1 1 2 4?。這些權值中,第三小的為2,輸出2,lastans變為?2。之后的操作類似。?
題解: 題目意思非常簡單,如果沒有連邊操作,就是普通的在一顆樹中求第k大,那么有連邊操作怎么辦? 連邊不就是將連個樹合并嗎? 所以——————啟發式合并(什么是啟發式合并? 就是一個東西啟發了你,你去合并就是啟發式合并,這里我們用子樹大小作為啟 發)
1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<cmath>
5 #include<algorithm>
6 #define maxn 80005
7 #define maxnode 20000005
8 using namespace std;
9 int ssize,tot,n,m,q,ans;
10 int rt[maxnode],rs[maxnode],ls[maxnode];
11 int pre[maxn*
2 ],v[maxn*
2 ],now[maxn*
2 ],fa[maxn],deep[maxn],a[maxn],list[maxn],size[maxn],sum[maxnode];
12 int bin[
21 ];
13 int f[maxn][
21 ];
14 bool vis[maxn];
15 int read()
16 {
17 int x=
0 ;
char ch;
bool bo=
0 ;
18 while (ch=getchar(),ch<
' 0 ' ||ch>
' 9 ' )
if (ch==
' - ' ) bo=
1 ;
19 while (x=x*
10 +ch-
' 0 ' ,ch=getchar(),ch>=
' 0 ' &&ch<=
' 9 ' );
20 if (bo)
return -x;
return x;
21 }
22 void prework()
23 {
24 bin[
0 ]=
1 ;
25 for (
int i=
1 ; i<=
20 ; i++) bin[i]=bin[i-
1 ]<<
1 ;
26 for (
int i=
1 ; i<=n; i++) fa[i]=i,size[i]=
1 ;
27 }
28 void ins(
int x,
int y){++tot; pre[tot]=now[x]; now[x]=tot; v[tot]=
y;
29 }
30 int find(
int x)
31 {
32 if (fa[x]!=x) fa[x]=
find(fa[x]);
33 return fa[x];
34 }
35 void insert(
int x,
int &y,
int l,
int r,
int k)
36 {
37 y=++ssize; sum[y]=sum[x]+
1 ;
38 if (l==r)
return ;
int mid=(l+r)>>
1 ;
39 if (k<=mid){ rs[y]=
rs[x]; insert(ls[x],ls[y],l,mid,k); }
40 else { ls[y]=ls[x]; insert(rs[x],rs[y],mid+
1 ,r,k); }
41 }
42 void dfs(
int x,
int dad)
43 {
44 deep[x]=deep[dad]+
1 ; f[x][
0 ]=
dad;
45 for (
int i=
1 ; i<=
16 ; i++
)
46 f[x][i]=f[f[x][i-
1 ]][i-
1 ];
47 insert(rt[dad],rt[x],
1 ,n,a[x]);
48 for (
int p=now[x]; p; p=
pre[p])
49 {
50 int son=
v[p];
51 if (son!=
dad) dfs(son,x);
52 }
53 }
54 void link(
int x,
int y)
55 {
56 int u=find(x),v=
find(y);
57 if (size[u]>
size[v]) swap(x,y),swap(u,v);
58 fa[u]=v; size[v]+=
size[u];
59 ins(x,y); ins(y,x); dfs(x,y);
60 }
61 int lca(
int x,
int y)
62 {
63 if (deep[x]<
deep[y]) swap(x,y);
64 int t=deep[x]-deep[y],i=
0 ;
65 if (x==y)
return x;
66 while (bin[i]<=
t)
67 {
68 if (t&bin[i]) x=
f[x][i];
69 i++
;
70 }
71 for (
int i=
16 ; i>=
0 ; i--
)
72 if (f[x][i]!=f[y][i]) x=f[x][i],y=
f[y][i];
73 if (x==y)
return x;
else return f[x][
0 ];
74 }
75 int query(
int x,
int y,
int val)
76 {
77 int uu=lca(x,y),vv=f[uu][
0 ];
78 x=rt[x]; y=rt[y]; uu=rt[uu],vv=
rt[vv];
79 int l=
1 ,r=
n;
80 while (l<
r)
81 {
82 int mid=(l+r)>>
1 ,kk=sum[ls[x]]+sum[ls[y]]-sum[ls[uu]]-
sum[ls[vv]];
83 if (val<=kk) {x=ls[x],y=ls[y],vv=ls[vv],uu=ls[uu],r=
mid;}
84 else {x=rs[x],y=rs[y],vv=rs[vv],uu=rs[uu],l=mid+
1 ;val-=
kk;}
85 }
86 return l;
87 }
88 void init()
89 {
90 int z=
read();
91 n=read(); m=read(); q=
read();
92 prework();
93 for (
int i=
1 ; i<=n; i++) list[i]=a[i]=
read();
94 sort(list+
1 ,list+
1 +
n);
95 for (
int i=
1 ; i<=n; i++) a[i]=lower_bound(list+
1 ,list+
1 +n,a[i])-
list;
96 for (
int i=
1 ; i<=m; i++
)
97 {
98 int x=read(),y=
read();
99 link(x,y);
100 }
101 for (
int i=
1 ; i<=n; i++
)
102 if (!deep[i]) dfs(i,
0 );
103 char ch;
104 ans=
0 ;
105 while (q--
)
106 {
107 ch=getchar();
while (ch<
' A ' || ch>
' Z ' ) ch=
getchar();
108 int x=read()^ans,y=read()^
ans,val;
109 if (ch==
' Q ' )
110 {
111 val=read()^
ans;
112 printf(
" %d\n " ,ans=
list[query(x,y,val)]);
113 }
114 else link(x,y);
115 }
116 }
117 int main()
118 {
119 init();
120 }
View Code ?
轉載于:https://www.cnblogs.com/HQHQ/p/5449036.html
總結
以上是生活随笔 為你收集整理的bzoj3123 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。