#include<iostream>usingnamespace std;constint N =100010;int p[N];intfind(int x)//返回x的祖宗结点 {if(p[x]!= x) p[x]=find(p[x]);return p[x];}intmain(){scanf("%d%d",&n ,&m);for(int i =1; i <= n ; i++) p[i]= i;while(m--){char op[2];int a, b;scanf("%s%d%d", op ,&a ,&b)if(op[0]=='M') p[find(a)]=find(b);else{if(find(a)=find(b))puts("Yes");elseputs("No");}}return0;}
Disjoint-set - communication block
#include<iostream>usingnamespace std;constint N =100010;int p[N], size[N];intfind(int x)//返回x的祖宗结点 {if(p[x]!= x) p[x]=find(p[x]);return p[x];}intmain(){int n , m;char op[5];scanf("%d%d",&n ,&m);for(int i =1; i <= n ; i++){
p[i]= i;
size[i]=1;}while(m--){int a , b;scanf("%s", op);if(op[0]=='C'){scanf("%d%d",&a ,&b);if(find(a)==find(b))continue;//如国重复就不用加了
size[find(b)]+= size[find(a)];
p[find(a)]=find(b);}elseif(op[1]=='1'){scanf("%d%d",&a ,&b);if(find(a)==find(b))puts("Yes");elseputs("No");}else{scanf("%d",&a);printf("%d\n", size[find(a)]);}}return0;}
Analog heap
#include<iostream>#include<algorithm>#include<string.h>usingnamespace std;constint N =100010;int h[N], ph[N], hp[N],size;//ph存的是第k个插入点是 , hp堆里面的第几个点是第k次插入的 voidheap_swap(int a ,int b){swap(ph[hp[a]], ph[hp[b]]);swap(hp[a], hp[b]);swap(h[a], h[b]);}voiddown(int u){int t = u;//t是三个中最小值 if(u *2<= size && h[2*u]< h[t]) t =2* u;//子节点存在且 if(u *2+1<= size && h[2*u +1]< h[t]) t =2*u +1;if(u != t){heap_swap(u , t);down(t);}}voidup(int u){while(u /2&& h[u /2]> h[u]){heap_swap(u , u /2);
u /=2;}}intmain(){int n , m =0;scanf("%d",&n);while( n--){char op[10];int k , x;scanf("%s", op);if(!strcmp(op ,"I")){scanf("%d",&x);
size++;//记录插入了几个数 (下标)
m++;//当前是第几个插入的数
ph[m]= size , hp[size]= m;
h[size]= x;up(size);}elseif(!strcmp(op ,"PM"))printf("%d\n", h[1]);elseif(!strcmp(op ,"DM"))//删除堆中最小的数 {heap_swap(1, size);
size--;down(1);}elseif(!strcmp(op ,"D"))//删除第K个插入的数 {scanf("%d",&k);
k = ph[k];heap_swap(k , size);
size--;down(k),up(k);}else{scanf("%d%d",&k ,&x);//修改第k个插入的数
k = ph[k];
h[k]= x;down(k),up(k);}}return0;}
Analog hash (hash table addressing method zipper open method)
#include<iostream>#include<cstring>usingnamespace std;constint N =1e5+3;//最好是除以一个质数int h[N], e[N], ne[N], idx;voidinsert(int x){int k =(x % N + N)% N;
e[idx]= x;//当前点的值
ne[idx]= h[k];//指针
h[k]= idx++;//存放在这一个里面的数加一 }boolfind(int x){int k =(x % N + N)%N;for(int i = h[k]; i !=-1; i = ne[i]){if(e[i]== x)returntrue;}returnfalse;}intmain(){int n;scanf("%d",&n );memset(h ,-1,sizeof(h));while( n--){char op[2];int x;scanf("%s%d", op ,&x);if(*op =='I')insert(x);else{if(find(x))puts("Yes");elseputs("No");}}return0;}
String hash
#include<iostream>usingnamespace std;typedefunsignedlonglong ULL;//ULL的范围是[0,2^64-1]. 1019数量级LL的范围是[-2^63,2^63-1]. 1018数量级constint N =100010, P =131;int n , m;char str[N];
ULL h[N], p[N];
ULL get(int l ,int r){return h[r]- h[l -1]* p[r - l +1];}intmain(){scanf("%d%d%s",&n ,&m , str +1);
p[0]=1;//p静止 for(int i=1; i <= n ; i++){
p[i]= p[i -1]* P;
h[i]= h[i -1]* P + str[i];}while( m--){int l1 , r1 , l2 , r2;scanf("%d%d%d%d",&l1 ,&r1 ,&l2 ,&r2);if(get(l1 , r1)==get(l2 , r2))puts("Yes");elseputs("No");}return0;}//8 3//aabbaabb//1 3 5 7//1 3 6 8//1 2 1 2