zoukankan      html  css  js  c++  java
  • 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
    ",g);
    88     else
    89     printf("-1
    ");
    90     return 0;
    91 }
    View Code
  • 相关阅读:
    linux getch()实现
    cppcheck 下载与安装(Liunx)
    apt-get 命令
    nanopb 文档
    VS调试技术
    c 单元测试 check
    GDB 调试
    GCC选项 –I,-l,-L
    作业66
    zhuoye
  • 原文地址:https://www.cnblogs.com/shangyu/p/3349385.html
Copyright © 2011-2022 走看看