标签:
并查集+离散化:首先了解怎么用并查集,数列是由0和1组成的,0和1总是有很多特别的解法,例如此题,ran[x]表示总和sum[0~x],同时ta也是1的个数num[0~x],而题中只有两种表达,odd和even所以就更方便了。并且num[l~r] = ran[r] - ran[l-1];所以输入num[l~r] = odd or even -> ran[r] - ran[l-1] = 1 or 0;并查集内ran值的关系搞出来了,就so easy 了。然后是离散化,第一次打离散代码,忘记此题数组范围需要扩大2倍了,注意!先搞个数组将输入值记录下来 -> sort一下 -> unique函数去重 -> 在运用数据时二分搜索找到相对应的序号值;就这样了。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int pre[5005*2]; int ran[5005*2]; int num[5005*2]; int a[5005],b[5005]; char ch[5005][10]; int n,cnt; void init(){ for(int i = 0; i < cnt; i++){ pre[i] = i; ran[i] = 0; } } int findl(int x){ int l = 0,r = cnt-1; while(l <= r){ int mid = (l+r)>>1; if(num[mid] == x)return mid; else if(num[mid] > x){ r = mid-1; } else l = mid+1; } } int find(int x){ if(pre[x] == x) return pre[x]; int fx = pre[x]; pre[x] = find(pre[x]); ran[x] += ran[fx]; ran[x] %= 2; return pre[x]; } int main(){ int T,x,y,d; bool flag = 0; scanf("%d%d",&n,&T); int ans = T; cnt = 0; for(int i = 0; i < T; i++){ scanf("%d%d%s",&a[i],&b[i],ch[i]); num[cnt++] = --a[i]; num[cnt++] = b[i]; } sort(num,num+cnt); cnt = unique(num,num+cnt) - num; init(); for(int i = 0; i < T; i++){ x = findl(a[i]); y = findl(b[i]); if(ch[i][0] == ‘e‘) d = 0; else d = 1; int fx = find(x); int fy = find(y); if(fx == fy){ if((ran[x] - ran[y] + 2) % 2 != d && !flag){ flag = 1;ans = i; } } else { pre[fx] = fy; ran[fx] = (ran[y] - ran[x] + 2 + d) % 2; } } printf("%d\n",ans); return 0; }
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int pre[5005*2]; int ran[5005*2]; int num[5005*2]; int a[5005],b[5005]; char ch[5005][10]; int n,cnt; void init(){ for(int i = 0; i < cnt; i++){ pre[i] = i; ran[i] = 0; } } int findl(int x){ int l = 0,r = cnt-1; while(l <= r){ int mid = (l+r)>>1; if(num[mid] == x)return mid; else if(num[mid] > x){ r = mid-1; } else l = mid+1; } } int find(int x){ if(pre[x] == x) return pre[x]; int fx = pre[x]; pre[x] = find(pre[x]); ran[x] ^= ran[fx]; return pre[x]; } int main(){ int T,x,y,d; bool flag = 0; scanf("%d%d",&n,&T); int ans = T; cnt = 0; for(int i = 0; i < T; i++){ scanf("%d%d%s",&a[i],&b[i],ch[i]); num[cnt++] = --a[i]; num[cnt++] = b[i]; } sort(num,num+cnt); cnt = unique(num,num+cnt) - num; init(); for(int i = 0; i < T; i++){ x = findl(a[i]); y = findl(b[i]); if(ch[i][0] == ‘e‘) d = 0; else d = 1; int fx = find(x); int fy = find(y); if(fx == fy){ if(ran[x]^ran[y] != d && !flag){ flag = 1;ans = i; } } else { pre[fx] = fy; ran[fx] = ran[y]^ran[x]^d; } } printf("%d\n",ans); return 0; }
标签:
原文地址:http://www.cnblogs.com/ACMessi/p/4840935.html