zoukankan      html  css  js  c++  java
  • ural 1003 Parity 并查集

    题意   就是一个小孩报数字;问从a ~ b 是奇还是偶 然后出现矛盾时,判断矛盾是什么时候出现;输出前面有多少句是对的

    解题   这题 确实是有点难度;一开始怎么也没有想清楚;想清楚还是蛮简单的;首先要明白一个原理,那就是从哪里到哪里是奇偶 有断点就可以决定,所以只与端点有关系;所以把所有想法都放到端点上来;端点与端点之间只有 奇偶性不同和相同的关系;可以用并查集 + ^(亦或运算)同时操作解决;首先如果两个点有关系,则把这两个点放在同一个集合里面,祖先到祖先的距离永远赋值为0 然后同一个集合的元素还好说;在进行 压缩路径的时候 同时更新一下 距离;如果两个不同的集合要变成一个集合;同理  和上一个题目一样,列举一个方程式;就出来了;~~

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 struct date
     8 {
     9    int sta,end,vis;
    10 }cnt[50005];
    11 int arr[100009],f[100009],r[100009];
    12 
    13 int find( int x )
    14 {
    15     if( f[x] != x )
    16     {
    17         int t = find( f[x]);
    18         r[x] ^= r[f[x]];
    19         f[x] = t;
    20         return t;
    21     }
    22     return x;
    23 }
    24 
    25 int search( int l,int r,int key )
    26 {
    27     int mid = ( l + r )>>1;
    28     if( arr[mid] == key )  return mid;
    29     if( arr[mid] >= key )  return search( l,mid,key );
    30     else                   return search( mid+1,r,key );
    31 }
    32 
    33 int main( )
    34 {
    35     int len,N,sta,end,i,k,t;
    36     char str[7];
    37     while( scanf("%d",&len) && len != -1 )
    38     {
    39         scanf("%d",&N);  k = 0;
    40         for( i = 1; i <= N; i++ )
    41         {
    42             scanf("%d%d%s",&cnt[i].sta,&cnt[i].end,&str);
    43             if( str[0] == 'e' ) cnt[i].vis = 0;
    44             else                cnt[i].vis = 1;
    45             arr[++k] = cnt[i].sta-1;
    46             arr[++k] = cnt[i].end;
    47         }
    48         sort( &arr[1],&arr[1]+k );
    49         t = 1;
    50         for( i = 2; i <= k; i++ )
    51         if( arr[i] != arr[t] )
    52             arr[++t] = arr[i];
    53         for( i = 0; i <= 100001; i++ )
    54             f[i] = i,r[i] = 0;
    55         for( i = 1; i <= N; i++ )
    56         {
    57             sta = cnt[i].sta-1; end =  cnt[i].end;
    58             sta = search( 1,t,sta )+1;
    59             end = search( 1,t,end )+1;
    60             int a = find(sta);
    61             int b = find(end);
    62             f[a] = b;
    63             if( a == b )
    64             {
    65                     if(  cnt[i].vis && r[sta] == r[end] )
    66                     {
    67                         printf("%d\n",i-1);break;
    68                     }
    69                     if( !cnt[i].vis && r[sta] != r[end] )
    70                     {
    71                         printf("%d\n",i-1);break;
    72                     }
    73             }
    74             else  r[a] = r[sta]^r[end]^cnt[i].vis;
    75         }
    76         if( i == N+1 ) printf("%d\n",N);
    77     }
    78     return 0;
    79 }
    80 /*
    81 10 5
    82 1 2 even
    83 3 4 old
    84 5 6 even
    85 1 6 even
    86 7 8 old
    87 */
  • 相关阅读:
    在 Java 应用程序中绑定 Bean 和数据
    JAVA的23种设计模式
    Windows 2012 Server评估版本安装问题处理
    从程序员到CTO的Java技术路线图
    MyBatis 学习
    CRT【p3868】[TJOI2009]猜数字
    线段树+扫描线【bzoj1645】[USACO07OPEN]城市的地平线City Horizon
    数学【CF743C】Vladik and fractions
    贪心【CF1029E】Tree with Small Distances
    线段树+二进制位拆分【CF242E】XOR on Segment
  • 原文地址:https://www.cnblogs.com/wulangzhou/p/2940528.html
Copyright © 2011-2022 走看看