Ural 1003 Parity(并查集)
2017-10-10 21:32
351 查看
题目地址:http://acm.timus.ru/problem.aspx?space=1&num=1003
思路:
一、
1.区间和可表示为两前缀和相减:sum[R]-sum[L-1]。若区间[L,R]和为奇数,则连边(L-1)-->R,权值为1,否则权值为0。则由a->b和b->c可推出a->c的奇偶性。
2.使用并查集维护信息,设w[i]为i到其根结点的距离。则判断时只需判断(w[L-1]+w[R])%2是否满足条件。
3.由此,得出sum[fa[R]]-sum[fa[L-1])=(w[R]-w[L-1]+p+2)%2(+2防止负数)。
二、
1.对于每点,设置两集合一代表其本身,另一代表其对立集合。
2.当一区间和为偶数时,fa[L-1]与fa[R]同属一集合,fa[(L-1)']与fa[R']同属一集合。
2.当一区间和为奇数时,fa[(L-1)]与fa[R']同属一集合,fa[(L-1)']与fa[R]同属一集合。
3.判断是否处于对应的集合即可。
思路:
一、
1.区间和可表示为两前缀和相减:sum[R]-sum[L-1]。若区间[L,R]和为奇数,则连边(L-1)-->R,权值为1,否则权值为0。则由a->b和b->c可推出a->c的奇偶性。
2.使用并查集维护信息,设w[i]为i到其根结点的距离。则判断时只需判断(w[L-1]+w[R])%2是否满足条件。
3.由此,得出sum[fa[R]]-sum[fa[L-1])=(w[R]-w[L-1]+p+2)%2(+2防止负数)。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define debug using namespace std; const int maxn=10000+50; struct Node { int l,r,id; }; int a[maxn]; Node q[maxn]; int cnt1,cnt2,n,m; int fa[maxn],w[maxn]; void init() { cnt1=cnt2=0; memset(w,0,sizeof(w)); for(int i=0; i<=m*2; i++) fa[i]=i; } int Find(int x) { if(fa[x]==x) { return x; } else { int t=fa[x]; fa[x]=Find(fa[x]); w[x]=(w[x]+w[t])%2; return fa[x]; } } int main() { #ifdef debu freopen("in.txt","r",stdin); #endif // debug while(scanf("%d",&n)!=EOF) { if(n==-1) break; scanf("%d",&m); init(); for(int i=0; i<m; i++) { int l,r; char st[5]; scanf("%d%d%s",&l,&r,st); a[cnt1++]=l,a[cnt1++]=r; q[cnt2].l=l,q[cnt2].r=r; q[cnt2].id=(st[0]=='e')?0:1; cnt2++; } sort(a,a+cnt1); int cnt=unique(a,a+cnt1)-a; int ans=-1; for(int i=0; i<cnt2; i++) { int l=lower_bound(a,a+cnt,q[i].l)-a+1; int r=lower_bound(a,a+cnt,q[i].r)-a+1; if(q[i].l>n||q[i].r>n) { ans=i+1; break; } int x=Find(l-1),y=Find(r); if(x==y) { if(q[i].id!=(w[l-1]+w[r])%2) { ans=i+1; break; } } else { fa[x]=y; w[x]=(w[r]-w[l-1]+q[i].id+2)%2; } } if(ans==-1) printf("%d\n",m); else printf("%d\n",ans-1); } return 0; }
二、
1.对于每点,设置两集合一代表其本身,另一代表其对立集合。
2.当一区间和为偶数时,fa[L-1]与fa[R]同属一集合,fa[(L-1)']与fa[R']同属一集合。
2.当一区间和为奇数时,fa[(L-1)]与fa[R']同属一集合,fa[(L-1)']与fa[R]同属一集合。
3.判断是否处于对应的集合即可。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define debug using namespace std; const int maxn=20000+50; struct Node { int l,r,id; }; Node q[maxn]; int n,m,cnt1,cnt2; int fa[maxn],a[maxn]; void init() { cnt1=cnt2=0; for(int i=0; i<=4*m+2; i++) fa[i]=i; } int Find(int x) { return fa[x]==x?x:fa[x]=Find(fa[x]); } int main() { #ifdef debu freopen("in.txt","r",stdin); #endif // debug while(scanf("%d",&n)!=EOF) { if(n==-1) break; scanf("%d",&m); init(); for(int i=0; i<m; i++) { int l,r; char st[5]; scanf("%d%d%s",&l,&r,st); a[cnt1++]=l,a[cnt1++]=r; q[cnt2].l=l,q[cnt2].r=r; q[cnt2].id=(st[0]=='e')?0:1,cnt2++; } sort(a,a+cnt1); int cnt=unique(a,a+cnt1)-a; int ans=-1; for(int i=0; i<m; i++) { int l=lower_bound(a,a+cnt,q[i].l)-a+1; int r=lower_bound(a,a+cnt,q[i].r)-a+1; if(q[i].l>n||q[i].r>n) { ans=i+1; break; } int x=Find(l-1),xx=Find(2*m+1+l-1); int y=Find(r),yy=Find(2*m+1+r); if(q[i].id==0) { if(x==yy||y==xx) { ans=i+1; break; } else { fa[x]=y; fa[xx]=yy; } } else { if(x==y||xx==yy) { ans=i+1; break; } else { fa[x]=yy; fa[xx]=y; } } } if(ans==-1) printf("%d\n",m); else printf("%d\n",ans-1); } return 0; }
相关文章推荐
- ural 1003 Parity 并查集
- Ural_1003 Parity(并查集)
- ural 1003. Parity(并查集)
- URAL 1003 Parity(并查集)
- 1003. Parity(并查集)
- URAL 1003 并查集
- Ural 1003 Parity
- URAL 1003 Parity
- URAL1003 Parity
- Ural(Timus) 1003 Parity
- 51nod 1204:Parity 并查集
- 51nod 1204 Parity[并查集]
- URAL 1320 Graph Decomposition(并查集)
- URAL1962:In Chinese Restaurant(并查集)
- URAL 2055 Urban Geography 分治,并查集
- ural 1982. Electrification Plan 并查集
- PKU1733 URAL1003 Parity game
- 1003 瑞神要考研(模拟,并查集)
- 【图论05】并查集 1003 Is It A Tree?
- 并查集 排列组合 In Chinese Restaurant:URAL - 1962