pku 1733 Parity game
其实很不好意思的说,这道题我的方法肯定不大好,非常的慢,需400多ms
但是再怎么说也是好不容易写出来的
这道题的转换方法很巧妙
要不是上网搜出来的,我肯定不敢相信这是用并查集做
主要是把区间化为单个数的想法来做
这一点的处理我是用cube stacking同样的想法来做的
还有一点,离散化,这是基本上资料对这题的所要求的一点,这一点我不大懂
这一题确实有个很大的特点,10亿的数据,只有5000个操作
离散化,还是要慢慢体会的
这是我的代码,很长,很繁琐
而且思路不是很清楚
因为边改边想着做出来的
1
#include
<
iostream
>
2 #include < string >
3 #include < map >
4 using namespace std;
5 typedef struct{
6 int parent;
7 // int rank;
8 int on ; // 决定从根到该结点的1的个数是奇还是偶,奇则为1,偶为0
9 }NODE;
10 typedef map < int ,NODE > Mate;
11 typedef Mate::value_type value_type;
12 Mate Map;
13 int find_set( int x)
14 {
15 int t = Map[x].parent;
16 if (Map[x].parent! = x){
17 Map[x].parent = find_set(Map[x].parent);
18 Map[x].on = (Map[x].on + Map[t].on)% 2 ;
19 }
20 return Map[x].parent;
21 }
22 void union_set( int x, int y, int c)
23 {
24 Map[y].parent = x;
25 Map[y].on = c;
26 }
27 int main()
28 {
29 NODE * t;
30 Mate::iterator xt,yt;
31 int i,n,qus,x,y,ct,xp,yp,k; // xp表示x - 1的祖先,yp表示y的祖先
32 string condi;
33 scanf( " %d%d " , & n, & qus);
34 for (i = 1 ;i <= qus;i ++ ){
35 cin >> x >> y >> condi;
36 if (condi == " even " )ct = 0 ;
37 else if (condi == " odd " )ct = 1 ;
38 xt = Map.find(x - 1 );
39 yt = Map.find(y);
40 if (xt! = Map.end() && yt! = Map.end()){ // x - 1 ,y都存在于Map中,但是也有不同的情况,可能二者在同一个集合中
41 // 可能二者也不在同一个集合中,如果在的话就好办了,直接验证
42 // 如果不则要合并
43 xp = find_set(x - 1 ); // find 一次 就更新了x - 1到根的路径上的on值
44 yp = find_set(y); // 同上
45 if (xp == yp){
46 if ((Map[y].on + Map[x - 1 ].on)% 2 ! = ct){
47 printf( " %d\n " ,i - 1 );
48 break;}}
49 k = (Map[x - 1 ].on + ct + Map[y].on)% 2 ;
50 if (xp < yp)union_set(xp,yp,k);
51 else union_set(yp,xp,k);
52 }
53 else if (xt! = Map.end() && yt == Map.end()){ // x - 1在Map中,而y不在
54 t = (NODE * )malloc(sizeof(NODE));
55 Map.insert(value_type(y, * t));
56 union_set(x - 1 ,y,ct);
57 }
58 else if (xt == Map.end() && yt! = Map.end()){ // x - 1不在Map中,而y在
59 yp = find_set(y);
60 t = (NODE * )malloc(sizeof(NODE));
61 Map.insert(value_type(x - 1 , * t));
62 union_set(yp,x - 1 ,(ct + Map[y].on)% 2 );
63 }
64 else if (xt == Map.end() && yt == Map.end()){ // x - 1和y都不在Map中
65 t = (NODE * )malloc(sizeof(NODE));
66 t -> on = 0 ;
67 t -> parent = x - 1 ;
68 Map.insert(value_type(x - 1 , * t));
69 t = (NODE * )malloc(sizeof(NODE));
70 Map.insert(value_type(y, * t));
71 union_set(x - 1 ,y,ct);
72 }
73 }
74 if (i > qus)printf( " %d\n " ,i - 1 );
75 return 0 ;
76 }
这是另外个代码,还没看懂
2 #include < string >
3 #include < map >
4 using namespace std;
5 typedef struct{
6 int parent;
7 // int rank;
8 int on ; // 决定从根到该结点的1的个数是奇还是偶,奇则为1,偶为0
9 }NODE;
10 typedef map < int ,NODE > Mate;
11 typedef Mate::value_type value_type;
12 Mate Map;
13 int find_set( int x)
14 {
15 int t = Map[x].parent;
16 if (Map[x].parent! = x){
17 Map[x].parent = find_set(Map[x].parent);
18 Map[x].on = (Map[x].on + Map[t].on)% 2 ;
19 }
20 return Map[x].parent;
21 }
22 void union_set( int x, int y, int c)
23 {
24 Map[y].parent = x;
25 Map[y].on = c;
26 }
27 int main()
28 {
29 NODE * t;
30 Mate::iterator xt,yt;
31 int i,n,qus,x,y,ct,xp,yp,k; // xp表示x - 1的祖先,yp表示y的祖先
32 string condi;
33 scanf( " %d%d " , & n, & qus);
34 for (i = 1 ;i <= qus;i ++ ){
35 cin >> x >> y >> condi;
36 if (condi == " even " )ct = 0 ;
37 else if (condi == " odd " )ct = 1 ;
38 xt = Map.find(x - 1 );
39 yt = Map.find(y);
40 if (xt! = Map.end() && yt! = Map.end()){ // x - 1 ,y都存在于Map中,但是也有不同的情况,可能二者在同一个集合中
41 // 可能二者也不在同一个集合中,如果在的话就好办了,直接验证
42 // 如果不则要合并
43 xp = find_set(x - 1 ); // find 一次 就更新了x - 1到根的路径上的on值
44 yp = find_set(y); // 同上
45 if (xp == yp){
46 if ((Map[y].on + Map[x - 1 ].on)% 2 ! = ct){
47 printf( " %d\n " ,i - 1 );
48 break;}}
49 k = (Map[x - 1 ].on + ct + Map[y].on)% 2 ;
50 if (xp < yp)union_set(xp,yp,k);
51 else union_set(yp,xp,k);
52 }
53 else if (xt! = Map.end() && yt == Map.end()){ // x - 1在Map中,而y不在
54 t = (NODE * )malloc(sizeof(NODE));
55 Map.insert(value_type(y, * t));
56 union_set(x - 1 ,y,ct);
57 }
58 else if (xt == Map.end() && yt! = Map.end()){ // x - 1不在Map中,而y在
59 yp = find_set(y);
60 t = (NODE * )malloc(sizeof(NODE));
61 Map.insert(value_type(x - 1 , * t));
62 union_set(yp,x - 1 ,(ct + Map[y].on)% 2 );
63 }
64 else if (xt == Map.end() && yt == Map.end()){ // x - 1和y都不在Map中
65 t = (NODE * )malloc(sizeof(NODE));
66 t -> on = 0 ;
67 t -> parent = x - 1 ;
68 Map.insert(value_type(x - 1 , * t));
69 t = (NODE * )malloc(sizeof(NODE));
70 Map.insert(value_type(y, * t));
71 union_set(x - 1 ,y,ct);
72 }
73 }
74 if (i > qus)printf( " %d\n " ,i - 1 );
75 return 0 ;
76 }
1
#include
<
stdio.h
>
2 #include < map >
3 using namespace std;
4
5 #define N 5001
6 int x[N], y[N], parent[N + N];
7 bool odd[N], parity[N + N];
8
9 void swap( int & a, int & b) {
10 int tmp = a; a = b; b = tmp;
11 }
12
13 map < int , int > mmp;
14
15 void unionab( int a, int b, bool e) {
16 parent[a] = b;
17 parity[a] = e;
18 }
19
20 int findx( int x, bool & e) {
21 int r = x;
22 bool res = parity[x];
23 while ( parent[r]! = r) {
24 r = parent[r];
25 res ^= parity[r];
26 }
27 e = res;
28 return r;
29 }
30
31 bool check( int id) {
32 int a = x[id], b = y[id];
33 bool e = odd[id], ea, eb;
34 int ra = findx(a, ea), rb = findx(b, eb);
35 if ( ra == rb) {
36 if ( ea ^ eb! = e)
37 return false ;
38 }
39 else
40 unionab( ra, rb, ea ^ eb ^ e);
41 return true ;
42 }
43
44 int main() {
45 int n, i, tmp, a,b, idx;
46 char s[ 7 ];
47 scanf( " %d%d " , & tmp, & n);
48 for ( i = 1 ,idx = 1 ; i <= n; i ++ ) {
49 scanf( " %d%d%s " , & a, & b,s);
50 if (a > b) swap(a,b);
51 -- a;
52 if (a < 0 ) {
53 printf( " 1\n " );
54 return 0 ;
55 }
56 if ( !mmp.count(a)) mmp[a] = idx ++ ;
57 if ( !mmp.count(b)) mmp[b] = idx ++ ;
58 x[i] = mmp[a]; y[i] = mmp[b];
59 odd[i] = (s[ 0 ] == ' o');
60 }
61 for ( i = 1 ; i <= idx; i ++ ) {
62 parent[i] = i; parity[i] = false ;
63 }
64 for ( i = 1 ; i <= n; i ++ ) {
65 if ( !check(i) )
66 break;
67 }
68 printf( " %d\n " , i - 1 );
69 return 0 ;
70 }
71
http://acm.pku.edu.cn/JudgeOnline/problem?id=1733
2 #include < map >
3 using namespace std;
4
5 #define N 5001
6 int x[N], y[N], parent[N + N];
7 bool odd[N], parity[N + N];
8
9 void swap( int & a, int & b) {
10 int tmp = a; a = b; b = tmp;
11 }
12
13 map < int , int > mmp;
14
15 void unionab( int a, int b, bool e) {
16 parent[a] = b;
17 parity[a] = e;
18 }
19
20 int findx( int x, bool & e) {
21 int r = x;
22 bool res = parity[x];
23 while ( parent[r]! = r) {
24 r = parent[r];
25 res ^= parity[r];
26 }
27 e = res;
28 return r;
29 }
30
31 bool check( int id) {
32 int a = x[id], b = y[id];
33 bool e = odd[id], ea, eb;
34 int ra = findx(a, ea), rb = findx(b, eb);
35 if ( ra == rb) {
36 if ( ea ^ eb! = e)
37 return false ;
38 }
39 else
40 unionab( ra, rb, ea ^ eb ^ e);
41 return true ;
42 }
43
44 int main() {
45 int n, i, tmp, a,b, idx;
46 char s[ 7 ];
47 scanf( " %d%d " , & tmp, & n);
48 for ( i = 1 ,idx = 1 ; i <= n; i ++ ) {
49 scanf( " %d%d%s " , & a, & b,s);
50 if (a > b) swap(a,b);
51 -- a;
52 if (a < 0 ) {
53 printf( " 1\n " );
54 return 0 ;
55 }
56 if ( !mmp.count(a)) mmp[a] = idx ++ ;
57 if ( !mmp.count(b)) mmp[b] = idx ++ ;
58 x[i] = mmp[a]; y[i] = mmp[b];
59 odd[i] = (s[ 0 ] == ' o');
60 }
61 for ( i = 1 ; i <= idx; i ++ ) {
62 parent[i] = i; parity[i] = false ;
63 }
64 for ( i = 1 ; i <= n; i ++ ) {
65 if ( !check(i) )
66 break;
67 }
68 printf( " %d\n " , i - 1 );
69 return 0 ;
70 }
71