标签:hid none print ace text pop 复杂 左右 维护
这道题目题目大意就是,刚开始有N个猴子,他们有一个战斗力
他们互相并不认识
使他们认识的唯一条件就是两个人干一发打一架
他们中会有M次打架发生,如果两个人互相认识了,他们就打不起来了,输出-1,
如果两个人不认识,那他们就会搞起来~两个人在搞完后战斗力会减半
随后两个人就会认识,并且这道题目里告诉我们朋友的朋友还是朋友~~~
输出这个块内战斗力最大是多少~~~
虽然我的解释比较简洁冗长,但是还是把题目大意说清楚了复杂了
这就是一道左偏树的裸题嘛
我们用并查集维护两个元素是否在同一个集合里
因为左偏树中已经存下了root,所以我们用起来就更爽了
虽然好简单啊啊啊啊啊
但是手贱的我犯下了一个极大的错误
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #define ll long long 7 #define fo(i,x,y) for(int i=x; i<=y; i++) 8 #define pr(i,x,y) for(int i=x; i>=y; i--) 9 #define clear(a,x) memset(a,x,sizeof(a)) 10 #define INF 1e9 11 #define EPS 1e-8 12 #define LiQin 1 > 0 13 14 using namespace std; 15 16 struct node 17 { 18 int l,r,d,w,root; 19 } tree[1000005]; 20 21 int N,M; 22 23 inline ll read() 24 { 25 int f=1; 26 ll Tmp=0; 27 char ch=getchar(); 28 while (ch != ‘-‘ && ch < ‘0‘ || ch > ‘9‘) 29 { 30 ch=getchar(); 31 } 32 if (ch == ‘-‘) 33 { 34 f=-1; 35 ch=getchar(); 36 } 37 while (ch >= ‘0‘ && ch <= ‘9‘) 38 { 39 Tmp=Tmp * 10 + ch - 48; 40 ch=getchar(); 41 } 42 return Tmp * f; 43 } 44 45 int merge(int A,int B) 46 { 47 if (A == 0) 48 { 49 return B; 50 } 51 if (B == 0) 52 { 53 return A; 54 } 55 if (tree[A].w < tree[B].w) 56 { 57 swap(A,B); 58 } 59 tree[A].r=merge(tree[A].r,B); 60 tree[tree[A].r].root=A; 61 if (tree[tree[A].l].d < tree[tree[A].r].d) 62 { 63 swap(tree[tree[A].l].d , tree[tree[A].r].d);//相信大佬们已经看出来了,这里交换的是左右儿子,而不是左右儿子的dist 64 } 65 if (tree[A].r) 66 { 67 tree[A].d=tree[tree[A].r].d + 1; 68 } 69 else 70 { 71 tree[A].d=0; 72 } 73 return A; 74 } 75 76 int pop(int u) 77 { 78 int L=tree[u].l; int R=tree[u].r; 79 tree[u].l=tree[u].r=tree[u].d=0; 80 tree[L].root=L; tree[R].root=R; 81 return merge(L,R); 82 } 83 84 int find1(int X) 85 { 86 if (tree[X].root != X) 87 { 88 return find1(tree[X].root); 89 } 90 else return X; 91 } 92 93 void solve(int u,int v) 94 { 95 int fx=find1(u); int fy=find1(v); 96 tree[fx].w/=2; tree[fy].w/=2; 97 int XXX=pop(fx); int YYY=pop(fy); 98 XXX=merge(XXX,fx); 99 YYY=merge(YYY,fy); 100 XXX=merge(XXX,YYY); 101 printf("%d\n",tree[XXX].w); 102 } 103 104 void Init() 105 { 106 fo(i,1,N) 107 { 108 tree[i].root=i; 109 tree[i].l=tree[i].r=tree[i].d=0; 110 } 111 } 112 113 int main() 114 { 115 while (scanf("%d",&N) == 1) 116 { 117 Init(); 118 fo(i,1,N) 119 { 120 tree[i].w=read(); 121 } 122 M=read(); 123 while (M--) 124 { 125 int u=read(); 126 int v=read(); 127 int fx=find1(u); 128 int fy=find1(v); 129 if (fx == fy) 130 { 131 printf("-1\n"); 132 } 133 else 134 { 135 solve(u,v); 136 } 137 } 138 } 139 }
好了好了
下面才是AC代码
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #define ll long long 7 #define fo(i,x,y) for(int i=x; i<=y; i++) 8 #define pr(i,x,y) for(int i=x; i>=y; i--) 9 #define clear(a,x) memset(a,x,sizeof(a)) 10 #define INF 1e9 11 #define EPS 1e-8 12 #define LiQin 1 > 0 13 14 using namespace std; 15 16 struct node 17 { 18 int l,r,d,w,root; 19 } tree[1000005]; 20 21 int N,M; 22 23 inline ll read() 24 { 25 int f=1; 26 ll Tmp=0; 27 char ch=getchar(); 28 while (ch != ‘-‘ && ch < ‘0‘ || ch > ‘9‘) 29 { 30 ch=getchar(); 31 } 32 if (ch == ‘-‘) 33 { 34 f=-1; 35 ch=getchar(); 36 } 37 while (ch >= ‘0‘ && ch <= ‘9‘) 38 { 39 Tmp=Tmp * 10 + ch - 48; 40 ch=getchar(); 41 } 42 return Tmp * f; 43 } 44 45 int merge(int A,int B) 46 { 47 if (A == 0) 48 { 49 return B; 50 } 51 if (B == 0) 52 { 53 return A; 54 } 55 if (tree[A].w < tree[B].w) 56 { 57 swap(A,B); 58 } 59 tree[A].r=merge(tree[A].r,B); 60 tree[tree[A].r].root=A; 61 if (tree[tree[A].l].d < tree[tree[A].r].d) 62 { 63 swap(tree[A].l , tree[A].r); 64 } 65 if (tree[A].r) 66 { 67 tree[A].d=tree[tree[A].r].d + 1; 68 } 69 else 70 { 71 tree[A].d=0; 72 } 73 return A; 74 } 75 76 int pop(int u) 77 { 78 int L=tree[u].l; int R=tree[u].r; 79 tree[u].l=tree[u].r=tree[u].d=0; 80 tree[L].root=L; tree[R].root=R; 81 return merge(L,R); 82 } 83 84 int find1(int X) 85 { 86 if (tree[X].root != X) tree[X].root=find1(tree[X].root); 87 return tree[X].root; 88 } 89 90 void solve(int u,int v) 91 { 92 int fx=find1(u); int fy=find1(v); 93 tree[fx].w/=2; tree[fy].w/=2; 94 int XXX=pop(fx); int YYY=pop(fy); 95 XXX=merge(XXX,fx); 96 YYY=merge(YYY,fy); 97 XXX=merge(XXX,YYY); 98 printf("%d\n",tree[XXX].w); 99 } 100 101 int main() 102 { 103 while (scanf("%d",&N) == 1) 104 { 105 fo(i,1,N) 106 { 107 tree[i].w=read(); 108 tree[i].root=i; 109 tree[i].l=tree[i].r=tree[i].d=0; 110 } 111 M=read(); 112 while (M--) 113 { 114 int u=read(); 115 int v=read(); 116 int fx=find1(u); 117 int fy=find1(v); 118 if (fx == fy) 119 { 120 printf("-1\n"); 121 } 122 else 123 { 124 solve(u,v); 125 } 126 } 127 } 128 }
标签:hid none print ace text pop 复杂 左右 维护
原文地址:http://www.cnblogs.com/TUncleWangT/p/7470628.html