• hdu5514 非2的次幂容斥原理


     1 /*
     2 1
     3 126 223092870
     4 210 330 390 462 510 546 570 690 714 770 798 858 910 966 1122 1155 1190 1254 1326 1330 1365 1430 1482 1518 1610 1785 1794 1870 1938 1995 2002 2090 2145 2210 2346 2415 2470 2530 2618 2622 2805 2926 2990 3003 3094 3135 3230 3315 3458 3542 3705 3795 3910 3927 4186 4370 4389 4485 4522 4641 4845 4862 5005 5187 5313 5434 5474 5865 6118 6279 6545 6555 6578 6783 7106 7293 7315 7735 8151 8211 8398 8602 8645 8855 9177 9614 9867 10166 10465 10659 11305 11362 12155 12597 12903 13585 13685 14421 14858 15249 15295 16445 17017 17043 17765 19019 20995 21505 22287 23023 24035 24871 25415 28405 29393 30107 33649 35581 37145 39767 46189 52003 55913 62491 81719 96577 
     5 */
     6 #include <cstdio>
     7 #include <queue>
     8 #include <cstring>
     9 #include <iostream>
    10 #include <cstdlib>
    11 #include <algorithm>
    12 #include <vector>
    13 #include <map>
    14 #include <set>
    15 #include <ctime>
    16 #include <cmath>
    17 #include <cctype>
    18 #define N 10000
    19 #define LL long long
    20 #define U unsigned
    21 using namespace std;
    22 int cas=1,T;
    23 int n,m,a[N+10],d[N+10],dn,v[N+10],c[N+10];
    24 int gcd(int a,int b)
    25 {
    26     return b==0?a:gcd(b,a%b);
    27 }
    28 void fac()
    29 {
    30     dn=0;
    31     int x=sqrt(m)+0.5;
    32     for(int i=1;i<=x;i++)
    33     {
    34         if(m%i==0)
    35         {
    36             d[dn++]=i;
    37             d[dn++]=m/i;
    38         }
    39     }
    40     sort(d,d+dn);
    41 }
    42 int main()
    43 {
    44     //freopen("1.in","w",stdout);
    45     //freopen("1.in","r",stdin);
    46     //freopen("out1","w",stdout);
    47     scanf("%d",&T);
    48     while(T--)
    49     {
    50         memset(v,0,sizeof(v));//要走的次数
    51         memset(c,0,sizeof(c));//已经走的次数
    52         scanf("%d%d",&n,&m);
    53         set<int>g;
    54         for(int i=0;i<n;i++) { scanf("%d",a+i);g.insert(gcd(m,a[i]%m)); }
    55         fac();
    56         for(set<int>::iterator it=g.begin();it!=g.end();it++)        //初始化,*it的倍数约数都要走一次
    57         {
    58             for(int j=0;j<dn;j++) if(d[j]% *it==0) v[j]=1;
    59         }
    60         LL ans=0;
    61         //for(int i=0;i<dn;i++) printf("%d ",d[i]);printf("
    ");
    62         for(int i=0;i<dn;i++)
    63         {
    64             if(v[i])
    65             {
    66                 int dif=v[i]-c[i];        //d[i]本来要走的次数-已经走了的次数=现在要走的次数
    67                 ans+=(LL)m*(m/d[i]-1)/2*dif;
    68                 for(int j=i+1;j<dn;j++) if(d[j]%d[i]==0) c[j]+=dif;//d[i]走过之后d[i]的倍数也已经走了dif次,所以c[j]+=dif
    69             }
    70         }
    71         printf("Case #%d: %lld
    ",cas++,ans);
    72     }
    73     //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
    74     return 0;
    75 }
    View Code
  • 相关阅读:
    leetcode 买卖股票的最佳时机3
    leetcode 买卖股票的最佳时机Ⅱ
    leetcode 最长有效括号
    C++中的%lld和%I64d区别
    Ural 1095 Nikifor 3 思维+同余性质的利用
    博弈基础
    ural 1091. Tmutarakan Exams
    容斥原理
    一些易错的地方
    codeforces911D Inversion Counting 求逆序数+小trick
  • 原文地址:https://www.cnblogs.com/cdyboke/p/5366155.html
Copyright © 2020-2023  润新知