【题解】SDOI2008莎拉公主的困惑

挺有趣的恩:洛谷P2155

在纸上打打草稿,写出n!个数,从先往后,遇到不互质的就筛掉——发现一个奇妙的性质!:筛掉的次数、顺序好像是周期性出现的呢~

而且更加妙妙的是,好像还是m!一轮..那么因为n!一定能被m!整除,所以问题转变为:(n!\m! - 有多少个循环节)*(φ(m))。

接下来,φ(m) = m!*(1 - 1/p1)*(1 - 1/p2)...任务就只剩下打出阶乘表&逆元啦。离线的处理会快很多。

#include <bits/stdc++.h>
using namespace std;
#define maxn 10000050
#define ll long long
#define int long long
int maxx, now = 1, P, T, tot, inv[maxn], ans[10050], pri[maxn],fac_a[maxn], fac_b[maxn], fac_c[maxn];
bool is_prime[maxn];
struct query
{
    int n, m, id, pri;
}Q[10050];

int read()
{
    int x = 0;
    char c;
    c = getchar();
    while(c < ‘0‘ || c > ‘9‘) c = getchar();
    while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = getchar();
    return x;
}

bool cmp1(query a, query b)
{
    return a.m < b.m;
}

int Get_Pri(int n)
{
    for(int i = 2; i <= n; i ++)
    {
        if(!is_prime[i])
        {
            pri[++ tot] = i;
            while(now <= T && pri[tot] > Q[now].m)
            {
                Q[now].pri = tot - 1;
                now ++;
            }
        }
        while(now <= T && i == n)
            {
                Q[now].pri = tot;
                now ++;
            }
        for(int j = 1; j <= tot; j ++)
        {
            if(i * pri[j] > n) break;
            is_prime[i * pri[j]] = 1;
            if(!(i % pri[j])) break;
        }
    }
}

int Get_fac(int n)
{
    fac_a[0] = fac_a[1] = fac_b[0] = fac_b[1] = fac_c[0] = fac_c[1] = 1;
    inv[0] = inv[1] = 1;
     for(int i = 2; i <= n; i ++)
     {
         fac_a[i] = (fac_a[i - 1] * i) % P;
        inv[i] = ((P - P / i) * inv[P % i]) % P;
    }
    for(int i = 1; i <= tot; i ++)
    {
        fac_b[i] = inv[pri[i]];
        fac_b[i] = (fac_b[i] * fac_b[i - 1]) % P;
        fac_c[i] = pri[i] - 1;
        fac_c[i] = (fac_c[i] * fac_c[i - 1]) % P;
    }
}

signed main()
{
    T = read(), P = read();
    for(int i = 1; i <= T; i ++)
    {
        Q[i].n = read(), Q[i].m = read(), Q[i].id = i;
        maxx = max(maxx, max(Q[i].n, Q[i].m));
    }
    sort(Q + 1, Q + 1 + T, cmp1);
    Get_Pri(maxx);
    Get_fac(maxx);
    for(int i = 1; i <= T; i ++)
        ans[Q[i].id] = ((fac_a[Q[i].n] * fac_b[Q[i].pri]) % P * fac_c[Q[i].pri]) % P;
    for(int i = 1; i <= T; i ++)
        printf("%lld\n", ans[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/twilight-sx/p/8416225.html

时间: 2024-10-13 14:47:02

【题解】SDOI2008莎拉公主的困惑的相关文章

【bzoj题解】2186 莎拉公主的困惑

题目传送门. 题意:求\([1,n!]\)中与\(m!\)互质的数的个数,对质数\(R\)取模,\(n\geq m\). 答案应该等于\(\frac{n!}{m!}\phi(m!)=\frac{n!}{m!}m!\prod_{p|m!}\frac{p-1}{p}=n!\frac{\prod_{p\leq m}\,p-1}{\prod_{p\leq m}\,p}\). 这里\(p\)为小于等于\(m\)的质数. 所以我们处理出阶乘,以及质数的乘积和对\(R\)的逆元就能得出答案. 你真的这么想?

【BZOJ2186】[Sdoi2008]沙拉公主的困惑 线性筛素数

[BZOJ2186][Sdoi2008]沙拉公主的困惑 Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量.现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可.R是一个质数. Input 第一行为两个整数T,R.R<=10^9+10,T<=10000,表示该组中测试数据数目,R为模后面T行,

【bzoj2186】[Sdoi2008]沙拉公主的困惑

2186: [Sdoi2008]沙拉公主的困惑 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 3303  Solved: 1129[Submit][Status][Discuss] Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量.现在,请你帮助沙拉公主解决这个问题,由于可能张数

bzoj2186【SDOI2008】沙拉公主的困惑

2186: [Sdoi2008]沙拉公主的困惑 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 2363  Solved: 779 [Submit][Status][Discuss] Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量.现在,请你帮助沙拉公主解决这个问题,由于可能张

【bzoj2186】: [Sdoi2008]沙拉公主的困惑 数论-欧拉函数

[bzoj2186]: [Sdoi2008]沙拉公主的困惑 考虑当 gcd(a,b)=1 则 gcd(nb+a,b)=1 所以[1,N!]与M!互质的个数就是 筛出[1,M]所有的素数p[i] 以及逆元 p[i]-1 处理一下前缀积inv[x]= 然后答案就是N!*inv[x] 1 /* http://www.cnblogs.com/karl07/ */ 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring&

bzoj2186: [Sdoi2008]沙拉公主的困惑

线性求逆元后好神的数论啊.... #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define rep(i,s,t) for(register int i=s;i<=t;i++) #define dwn(i,s,t) for(register int i=s;i>=t;i--) #define clr(x,c

bzoj 2186 [Sdoi2008]沙拉公主的困惑 欧拉函数

bzoj 2186 [Sdoi2008]沙拉公主的困惑 题意: 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量.现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可.R是一个质数. 限制: 数据组数T:1 <= T <= 10000 R <= 1e9+10 1 <= N,M <=10000000

2186: [Sdoi2008]沙拉公主的困惑 - BZOJ

Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量.现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可.R是一个质数. Input 第一行为两个整数T,R.R<=10^9+10,T<=10000,表示该组中测试数据数目,R为模后面T行,每行一对整数N,M,见题目描述 m<=n Outp

数学(逆元):BZOJ 2186: [Sdoi2008]沙拉公主的困惑

2186: [Sdoi2008]沙拉公主的困惑 Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一 大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量.现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可. R是一个质数. Input 第一行为两个整数T,R.R<=10^9+10,T<=10000,表示该组中测试数据数目,R为模后面T行,每行