hdu 5514 容斥原理

hdu 5514

题意: 有 n 只青蛙,一开始都在 0 点。有一堆围成一圈的石子,石子的编号是从 0 ~ (m-1)。 所有青蛙只能顺时针跳,每个青蛙可以一次跳a[i]格。问这些青蛙踩过的石子的编号总和是多少?

tags:  容斥经典题。

对 m 分解因子,对每个因子求贡献。

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 200005;

int T, n, m, pp[N], f[N], cnt;
ll  ans;
void get_pp(int mn)
{
    cnt=0;
    for(int i=1; i<=sqrt(mn); ++i)
        if(mn%i==0)
        {
            pp[++cnt]=i;
            if(mn/i != i) pp[++cnt]=mn/i;
        }
    sort(pp+1, pp+1+cnt);
    --cnt;
}
void Init()
{
    mes(f, 0);
    ans = 0;
}
int main()
{
    scanf("%d", &T);
    rep(cas, 1, T)
    {
        scanf("%d%d", &n, &m);
        Init();
        get_pp(m);
        int ai, tmp;
        rep(i,1,n)
        {
            scanf("%d", &ai);
            tmp = __gcd(ai, m);
            rep(j,1,cnt)
                if(pp[j]%tmp==0)
                    f[j] = 1;
        }
        ll  tmp1;
        rep(i,1,cnt)
            if(f[i])
            {
                tmp1 = (m-1)/pp[i];
                ans += tmp1*(tmp1+1)/2 * pp[i] * f[i];
                rep(j,i+1,cnt)
                    if(pp[j]%pp[i]==0)
                        f[j] -= f[i];
            }
        printf("Case #%d: %lld\n", cas, ans);
    }

    return 0;
}

原文地址:https://www.cnblogs.com/sbfhy/p/7800821.html

时间: 2024-08-04 18:41:47

hdu 5514 容斥原理的相关文章

Hdu 5514 Frogs (容斥原理)

题目链接: Hdu 5514 Frogs 题目描述: 有n只青蛙,m个石头(围成圆圈).第i只青蛙每次只能条ai个石头,问最后所有青蛙跳过的石头的下标总和是多少? 解题思路: 第一反应就是容斥,也是没谁了.但是重现赛的时候并没有做出来,自己写了一个容斥然后挂掉了,今天看到大神的方法,感觉这种处理方法有点神!(还是见的题目太少,太弱了) 第i只青蛙只能走到gcd(ai, m)的位置,我们就可以把m的因子提取出来,然后对青蛙能走到的因子位置打标记.青蛙能走到vis[i]因子位置就把vis[i]标记为

hdu 5514 Frogs(容斥)

Frogs Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1315    Accepted Submission(s): 443 Problem Description There are m stones lying on a circle, and n frogs are jumping over them.The stones a

hdu 1695 容斥原理或莫比乌斯反演

GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5310    Accepted Submission(s): 1907 Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y)

HDU 5514 Frogs

Frogs Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ID: 551464-bit integer IO format: %I64d      Java class name: Main There are m stones lying on a circle, and n frogs are jumping over them.The stones are numb

hdu 2597(容斥原理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5297: 题意:给出n和r,求数列Y的第n个元素是多少.其中数列Y是正整数数列去除a^b(2<=b<=r)后的数 分析: 我的天啊,出一个数n,则1~n以内的正整数必定会有被去除的(假设被去除x1个),则这n个数中只有(n-x1)个数在Y数列中:如果想得到n个数在Y数列中,那么我们至少要在这n个数后面加上x1个数,设n1=n+x1,则在1~n1内的数有多少在Y数列中呢(假设有m个在Y数列中,去除了x

HDU 4336 容斥原理 || 状压DP

状压DP :F(S)=Sum*F(S)+p(x1)*F(S^(1<<x1))+p(x2)*F(S^(1<<x2))...+1; F(S)表示取状态为S的牌的期望次数,Sum表示什么都不取得概率,p(x1)表示的是取x1的概率,最后要加一因为有又多拿了一次.整理一下就可以了. 1 #include <cstdio> 2 const int Maxn=23; 3 double F[1<<Maxn],p[Maxn]; 4 int n; 5 int main() 6

hdu 4135 容斥原理

又搞了一道容斥原理. 题目:求[1,n]区间对m互质的数有多少个? #include<iostream> #include<vector> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define LL __int64 const int maxn = 1e5+8; LL a[maxn],cn,numpri[maxn],vis[maxn]

HDU 1796 容斥原理

How many integers can you find Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7439    Accepted Submission(s): 2200 Problem Description Now you get a number N, and a M-integers set, you should

HDU 4059 容斥原理+快速幂+逆元

题目求1-n中与n互质的数的4次方之和,即S=a1^4+a2^4+……; a1,a2……均小于等于n且与n互质. 先求出1^4+2^4+……n^4然后减去与n不互质的数的4次方. 必然要先要用到4次方的求和公式.接下来简单的证明一下,这里前提是你知道3次方的公式,如果不会照下面的模式可以利用2次公式推出3次公式 (x+1)^5=x^5+5*x^4+10*x^3+10*x^2+5*x+1; 则 1=1; 2^5=(1+1)^5=1^5+5*1^4+10*1^3+10*1^2+5*1^1+1; 3^