给定N个点的坐标,代表N各城市,有M种操作,共分两种,一种是连线,把两个点连起来(一旦构成连通图,这个连通图即为一个州),还有种询问操作,为y=c,(c为小数部分恒为.5的实数),问y=c这条线经过了多少个大周,这些州总共有多少个城市
很明显要用到并查集,比较好的做法是把并查集落实到线段树上,并查集维护的是每个集合的最大y和最小y,以及rank表示集合数目。但是线段树要用到离散化、
然后参照一个用树状数组的博客,其实思路差不多,都是把每次的变更落实到树上
不过这个树状数组跟之前写的不一样,这个是改段查点型的,之前的是改点查段型的,其实只要改一下辅助数组的定义即可,在这个树状数组里面,把辅助数组d当做从1到当前所有的变更,每次更新时从当前往递减方向,所以,为了得到某个点值,必须把当前点以及当前之前的变更都加起来。
所以这个
add(int loc,int v)
{
while (loc>0){d[loc]+=v;loc-=lowbit(loc);}
}
query(int loc)
{
int ret=0;
while (loc<n) {ret+=d[loc];loc+=lowbit(loc);}
return ret;
}
因为给定的数是.5的实数,故意把坐标往后压一位即可,把每一个小格子往后压成一个点即可
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 int n,m; 8 int f[100010],rank[100010],y1[100010],y2[100010]; 9 void init() 10 { 11 for (int i=0;i<=n;i++){ 12 f[i]=i; 13 rank[i]=1; 14 } 15 } 16 int findset(int x) 17 { 18 if (x!=f[x]){ 19 f[x]=findset(f[x]); 20 } 21 return f[x]; 22 } 23 int lowbit(int x) 24 { 25 return x&(-x); 26 } 27 struct bit 28 { 29 int d[100010]; 30 int limit; 31 void clear() 32 { 33 memset(d,0,sizeof d); 34 } 35 void add(int L,int R,int v){ 36 while (R>=1){ 37 d[R]+=v; 38 R-=lowbit(R); 39 } 40 while (L>=1){ 41 d[L]+=-v; 42 L-=lowbit(L); //L这里不能算点,因为每个格子都往后压,每个点x,就代表x-1到x这个区间,所以在这里可以抵消L的格子的影响 43 } 44 } 45 int query(int x) 46 { 47 int ret=0; 48 while (x<=limit){ 49 ret+=d[x]; 50 x+=lowbit(x); 51 } 52 return ret; 53 } 54 }city,state; 55 void unit(int r1,int r2) 56 { 57 f[r1]=r2; 58 rank[r2]+=rank[r1]; 59 } 60 int main() 61 { 62 int t; 63 scanf("%d",&t); 64 int a,b; 65 double c; 66 char ch[10]; 67 while (t--) 68 { 69 city.clear(); 70 state.clear(); 71 scanf("%d",&n); 72 init(); 73 int maxn=0; 74 for (int i=0;i<n;i++){ 75 scanf("%d%d",&a,&b); 76 y1[i]=b;y2[i]=b; 77 maxn=max(maxn,b); 78 } 79 city.limit=state.limit=maxn; 80 scanf("%d",&m); 81 for (int i=1;i<=m;i++){ 82 scanf("%s",ch); 83 if (ch[0]=='r'){ 84 scanf("%d%d",&a,&b); 85 int r1=findset(a); 86 int r2=findset(b); 87 if (r1==r2) continue; 88 if (rank[r1]==1 && rank[r2]==1){ 89 unit(r1,r2); 90 y1[r2]=min(y1[r2],y1[r1]); 91 y2[r2]=max(y2[r2],y2[r1]); 92 city.add(y1[r2],y2[r2],1); 93 state.add(y1[r2],y2[r2],rank[r2]); 94 } 95 else 96 if (rank[r1]==1 || rank[r2]==1){ 97 if (rank[r1]==1) swap(r1,r2); 98 city.add(y1[r1],y2[r1],-1); 99 state.add(y1[r1],y2[r1],-rank[r1]); 100 unit(r1,r2); 101 y1[r2]=min(y1[r1],y1[r2]); 102 y2[r2]=max(y2[r1],y2[r2]); 103 city.add(y1[r2],y2[r2],1); 104 state.add(y1[r2],y2[r2],rank[r2]); 105 } 106 else 107 { 108 city.add(y1[r1],y2[r1],-1); 109 state.add(y1[r1],y2[r1],-rank[r1]); 110 111 city.add(y1[r2],y2[r2],-1); 112 state.add(y1[r2],y2[r2],-rank[r2]); 113 114 unit(r1,r2); 115 y1[r2]=min(y1[r1],y1[r2]); 116 y2[r2]=max(y2[r1],y2[r2]); 117 city.add(y1[r2],y2[r2],1); 118 state.add(y1[r2],y2[r2],rank[r2]); 119 } 120 } 121 else { 122 scanf("%lf",&c); 123 int tmp=c; 124 tmp++; 125 printf("%d %d ",city.query(tmp),state.query(tmp)); 126 } 127 } 128 } 129 return 0; 130 }