1682. Crazy Professor(并查集)

1628

加了些数论知识  先看下剩余类的概念

一个整数被正整数n除后,余数有n种情形:0,1,2,3,…,n-1,它们彼此对模n不同余。这表明,每个整数恰与这n个整数中某一个对模n同余。这样一来,按模n是否同余对整数集进行分类,可以将整数集分成n个两两不相交的子集。我们把(所有)对模n同余的整数构成的一个集合叫做模n的一个剩余类。

对于a%k=x b%k=y  若x!=y  a与b有边相连 则a的剩余类  与b的剩余类l里的元素也是可以相连的  即 a ->b->a+k->b+k->a 所以有环 

若x==y 则同一剩余类里元素都可以相连 a->a+k->a+2k->a 成环 且不会大于3*k

然后利用并查集就可以了 用vector存下可以与其满足对k取余为0的剩余类 枚举t t+k t+2*k时的情况 是不是形成 了环

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<stdlib.h>
 5 #include<vector>
 6 #include<algorithm>
 7 #include<cmath>
 8 using namespace std;
 9 #define N 300010
10 #define LL long long
11 vector<LL>q[N];
12 LL f[N];
13 LL find(LL x)
14 {
15     if(x!=f[x])
16     f[x] = find(f[x]);
17     return f[x];
18 }
19 int main()
20 {
21     LL i,j,k;
22     int flag = 0,g;
23     scanf("%lld",&k);
24     for(i = 0; i <= k*3; i++)
25     f[i] = i;
26     for(i = 0 ; i < k ; i++)
27     {
28         LL tt = (i*i)%k;
29         q[i].push_back((k-tt)%k);
30         q[(k-tt)%k].push_back(i);
31     }
32     for(i = 0 ; i < k ; i++)
33     sort(q[i].begin(),q[i].end());
34     for(i = 2; i <= k*3 ; i++)
35     {
36         int io = i%k;
37         int tt = unique(q[io].begin(), q[io].end()) - q[io].begin();
38         int t;
39         for(j = 0 ; j < tt ; j++)
40         {
41             t = q[io][j];
42             if(t<i&&t>0)
43             {
44                 int tx = find(i);
45                 int ty = find(t);
46 
47                 if(tx==ty)
48                 {
49                     flag = 1;
50                     break;
51                 }
52                 else
53                 f[tx] = ty;
54             }
55             if(t+k<i)
56             {
57                 int tx = find(i);
58                 int ty = find(t+k);
59                 if(tx==ty)
60                 {
61                     flag = 1;
62                     break;
63                 }
64                 else
65                 f[tx] = ty;
66             }
67             if(t+2*k<i)
68             {
69                 int tx = find(i);
70                 int ty = find(t+2*k);
71                 if(tx==ty)
72                 {
73                     flag = 1;
74                     break;
75                 }
76                 else
77                 f[tx] = ty;
78             }
79         }
80         if(flag)
81         {
82             g = i;
83             break;
84         }
85     }
86     if(flag)
87     printf("%d\n",g);
88     else
89     printf("-1\n");
90     return 0;
91 }
View Code

 

 

 

posted @ 2013-10-02 15:57  _雨  阅读(231)  评论(0编辑  收藏  举报