zoukankan      html  css  js  c++  java
  • HDU5514 容斥原理

    每次遇到容斥,都只会直接上莫比乌斯系数,方便快捷,这次1e9的GG了,实际上还是容斥,只不过这次并不需要很多数的容斥,只需要m的因子之间互相容斥一下就可以了。

    参考一份题解很不错,他文中提到的错误解法我们队训练时也这么想的。。http://m.blog.csdn.net/kevin66654/article/details/52724774

     1 #include <bits/stdc++.h>
     2 const long long mod = 1e9+7;
     3 const double ex = 1e-10;
     4 #define inf 0x3f3f3f3f
     5 using namespace std;
     6 long long tmp[11234];
     7 long long tmp2[11234];
     8 long long p[112342];
     9 int tt[112342];
    10 long long gcd(long long x,long long y){
    11     return y==0?x:gcd(y,x%y);
    12 }
    13 int main()
    14 {
    15     int T;
    16     scanf("%d",&T);
    17     for (int cas = 1 ; cas <= T; cas++){
    18         int n;
    19         long long m;
    20         scanf("%d%lld",&n,&m);
    21 
    22         for (int i = 1; i<=n; i++){
    23             scanf("%lld",&tmp[i]);
    24             tmp[i] = gcd(tmp[i],m);
    25         }
    26         sort(tmp+1,tmp+1+n);
    27         if (tmp[1]==1){
    28             printf("Case #%d: %lld
    ",cas,m*(m-1)/2);
    29             continue;
    30         }
    31         int cnt = 0;
    32         for (int i = 1 ; i<=n ;i++){
    33             int flag = 1;
    34             for (int j = 1; j<i ; j++){
    35                 if (tmp[i] % tmp[j] == 0 ) {
    36                     flag = 0;
    37                     break;
    38                 }
    39             }
    40             if (flag)tmp2[++cnt] = tmp[i];
    41         }
    42         tmp2[cnt+1] = mod;
    43         int cntt = 0;
    44         for (int i = 2 ; i*i<=m; i++){
    45             if (m%i==0) {
    46                 p[++cntt] = i;
    47                 if (i*i!=m) p[++cntt] = m/i;
    48             }
    49         }
    50         memset(tt,0,sizeof(tt));
    51         sort(p+1,p+cntt+1);
    52         int pos = 1;
    53         long long ans = 0;
    54         for (int i = 1; i<=cntt ; i++){
    55             if (tmp2[pos] == p[i]) ans += (m/tmp2[pos])*(m/tmp2[pos]-1)/2*tmp2[pos],pos++,tt[i] = 1;
    56             else{
    57                 int flag = 1;
    58                 for (int j = 1; tmp2[j] < p[i] ; j++){
    59                     if (p[i] % tmp2[j]==0) {flag = 0;break;}
    60                 }
    61                 if (flag) continue;
    62                 int t = 0;
    63                 for (int j = 1; j < i ; j++){
    64                     if (p[i] % p[j] == 0) {t+=tt[j];}
    65                 }
    66                 ans += (1-t) * (m/p[i])*(m/p[i]-1)/2*p[i] , tt[i]=(1-t);
    67             }
    68         }
    69         printf("Case #%d: %lld
    ",cas,ans);
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    初学Google Code,Subversion和TortoiseSVN
    成长,真有你想象的那样迫切?
    Java中十个常见的违规编码
    Eclipse打包工具Fatjar
    “旁观者效应”是如何毁掉我们的代码的
    java设计模式—分类
    java中的关键字static(静态变量)和final定义常量
    JAVA UDP打洞必备知识点NAT
    [Struts]在jsp里处理比较复杂的内容?
    反向链接referrer的原理
  • 原文地址:https://www.cnblogs.com/HITLJR/p/7650616.html
Copyright © 2011-2022 走看看