zoukankan      html  css  js  c++  java
  • HDU-5514 Frogs (容斥)

     题目链接:Frogs

    题意:有n只青蛙和m块石头(石头编号为0 - n-1)排成一个环,刚开始每只青蛙都在标号为0的石头上。每只青蛙每次跳a[i]的距离,但凡被青蛙经过的石头都会被占领,求这m块石头中所有被占领过的石头的编号和。

    题解:首先,可以发现每只青蛙跳过的石头的标号是gcd(a[i] , M)的倍数。所以把每只青蛙的gcd求出来后就是一个容斥了,容斥主要看代码领悟。如果出现了一个x = gcd(ai,m),那么所有x的倍数的因数都算是出现过了,在计算的时候如果把x的倍数都加了k遍,那么就要把pk的倍数减去k遍。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define fi first
     4 #define se second
     5 typedef long long LL;
     6 typedef pair<LL,int> P;
     7 const int MAX_N = 1e5+7;
     8 const LL inf = 0x3f3f3f3f3f3f3f3f;
     9 LL N,M,T,S;
    10 int vis[MAX_N];
    11 LL pi[MAX_N];
    12 int num;
    13 LL gcd(LL a,LL b){
    14     return b == 0?a : gcd(b,a%b);
    15 }
    16 void init(){
    17     num = 0;
    18     pi[num ++ ] = 1;
    19     for(int i=2;i*i<=M;i++){
    20         if(M%i == 0){
    21             if(i == M/i){
    22                 pi[num++] = i;
    23             }
    24             else{
    25                 pi[num++] = i;
    26                 pi[num++] = M/i;
    27             }
    28         }
    29     }
    30     sort(pi,pi+num);
    31     memset(vis,0,sizeof(vis));
    32 }
    33 int main(){
    34     cin>>T;
    35     int out = 0;
    36     while(T--){
    37         out ++;
    38         scanf("%lld%lld",&N,&M);
    39         init();
    40         for(int i=0;i<N;i++){
    41             LL t;
    42             scanf("%lld",&t);
    43             LL x = gcd(t,M);
    44             for(int j=0;j<num;j++){
    45                 if(pi[j]%x == 0){
    46                     vis[j] = 1;
    47                 }
    48             }
    49         }
    50 
    51         LL ans = 0;
    52         for(int i=0;i<num;i++){
    53             if(vis[i] != 0){
    54                 LL t = pi[i];
    55                 LL n = (M-1) / t;
    56                 ans +=  (t+n*t)*n/2*vis[i];
    57                 for(int j = i+1;j<num;j++)
    58                 {
    59                     if(pi[j] % pi[i] == 0){
    60                         vis[j] -= vis[i];
    61                     }
    62 
    63                 }
    64 
    65             }
    66         }
    67         printf("Case #%d: %lld
    ",out,ans);
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    HDU 5642 King's Order 动态规划
    HDU 5640 King's Cake GCD
    HDU 5641 King's Phone 模拟
    HDU 5299 Circles Game 博弈论 暴力
    HDU 5294 Tricks Device 网络流 最短路
    HDU 5289 Assignment rmq
    HDU 5288 OO’s Sequence 水题
    星际争霸 虚空之遗 人族5BB 操作流程
    Codeforces Beta Round #3 D. Least Cost Bracket Sequence 优先队列
    Codeforces Beta Round #3 C. Tic-tac-toe 模拟题
  • 原文地址:https://www.cnblogs.com/doggod/p/9748314.html
Copyright © 2011-2022 走看看