标签:树状数组
There are N seaside villages on X island, numbered from 1 to N. N roads are built to connect all of them, which are also numbered from 1 to N, and the road with number i connects the village i and i % N + 1. Sometimes, for some reasons, some roads are blocked, so some villages are not connected anymore. Now, you are assigned to write a program to offer dynamic information about the connectivity.At first, all roads are not blocked. The input will tell you the road with number i are blocked or unblocked, or ask you if village i and j are connected. Here two villages are connected means we can reach another village from one via some unblocked road. BTW, all the roads are bidirectional.
1 5 10 1 2 5 0 4 1 4 5 0 2 1 3 4 1 1 3 0 1 0 2 1 2 4 1 2 5
1 1 1 0 1 0
一开始以为是并查集,后来想想不能实现,看了别人的思路,发现因为连接的道路很有规律,所以可以用树状数组来实现,这题主要是判断两个点是否是相连的,这里因为是环装,所以两点有两种可能的连接顺序,一种是从小的数到大的数,另一种是从大的数到小的数。
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<queue> #include<stack> #include<string> #include<algorithm> using namespace std; int b[100005],n,zhi[100006]; int lowbit(int x){ return x&(-x); } void update(int pos,int num) { while(pos<=n){ b[pos]+=num;pos+=lowbit(pos); } } int getsum(int pos) { int num=0; while(pos>0){ num+=b[pos];pos-=lowbit(pos); } return num; } int main() { int m,i,j,T,a,c,d; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(i=1;i<=n;i++){ zhi[i]=1; b[i]=lowbit(i); } for(i=1;i<=m;i++){ scanf("%d",&a); if(a==0){ scanf("%d",&c); if(zhi[c]==1){update(c,-1);zhi[c]=0;} else {update(c,1);zhi[c]=1;} } else{ scanf("%d%d",&c,&d); if(c>d)swap(c,d); if( getsum(d-1)-getsum(c-1)==d-c || getsum(n)-getsum(d-1)+getsum(c-1)==c+n-d )printf("1\n"); else printf("0\n"); } } } return 0; }
标签:树状数组
原文地址:http://blog.csdn.net/kirito_acmer/article/details/46446559