zoukankan      html  css  js  c++  java
  • 【BZOJ 2186】 2186: [Sdoi2008]沙拉公主的困惑 (欧拉筛,线性求逆元)

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

    Description

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

    Input

    第一行为两个整数T,R。R<=10^9+10,T<=10000,表示该组中测试数据数目,R为模后面T行,每行一对整数N,M,见题目描述 m<=n

    Output

    共T行,对于每一对N,M,输出1至N!中与M!素质的数的数量对R取模后的值

    Sample Input

    1 11
    4 2

    Sample Output

    1

    数据范围:
    对于100%的数据,1 < = N , M < = 10000000

    HINT

    Source

    【分析】

      本来做这题是找信心,然而。。

      首先我们知道 如果x与y互质,那么x+y与y也互质。

      所以只需要求$phi(m!)* dfrac{n!}{m!} $

      问题转换成求$phi(m!)$

      我们知道一种求法,就是把$m!$分解质因数,对于每个素数乘上一个$dfrac{p-1}{p}$

      显然<=m的素数就是$m!$的分解质因数。

      中间要用到的线性求逆元:

      ny[1]=1;

      for(int i=2;i<=Maxn-10;i++) ny[i]=(R-R/i*ny[R%i])%R;

      

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 #define Maxn 10000010
     8 #define LL long long
     9 
    10 int R;
    11 
    12 int mul(int x,int y)
    13 {
    14     LL K1=(LL)x,K2=(LL)y;
    15     K1=(K1*K2)%R;
    16     return (int)K1;
    17 }
    18 
    19 int pri[Maxn],pl;
    20 int ny[Maxn];
    21 bool vis[Maxn];
    22 void init()
    23 {
    24     for(int i=2;i<=Maxn-10;i++)
    25     {
    26         if(!vis[i]) pri[++pl]=i;
    27         for(int j=1;j<=pl;j++)
    28         {
    29             LL K1=(LL)i,K2=(LL)pri[j];
    30             K1=K1*K2;
    31             if(K1>Maxn) break;
    32             vis[K1]=1;
    33             if(i%pri[j]==0) break;
    34         }
    35     }
    36 }
    37 
    38 int A[Maxn],B[Maxn];
    39 void get_ans()
    40 {
    41     A[1]=1;
    42     for(int i=2;i<=Maxn-10;i++)
    43     {
    44         A[i]=mul(A[i-1],i);
    45     }
    46     int now=1;
    47     B[1]=1;
    48     for(int i=2;i<=Maxn-10;i++)
    49     {
    50         B[i]=B[i-1];
    51         while(pri[now]<=i&&now<=pl)
    52         {
    53             B[i]=mul(mul(pri[now]-1,ny[pri[now]]),B[i]);
    54             // B[i]=((B[i]*(pri[now]-1)%R)%R)*ny[pri[now]];
    55             // B[i]%=R;
    56             now++;
    57             if(now==pl) break;
    58         }
    59     }
    60 }
    61 
    62 int main()
    63 {
    64     int T;
    65     scanf("%d%d",&T,&R);
    66     // memset(vis,0,sizeof(vis));
    67     for(int i=1;i<=Maxn-10;i++) vis[i]=0;
    68     init();
    69     ny[1]=1;
    70     for(int i=2;i<=Maxn-10;i++) ny[i]=mul(R-R/i,ny[R%i]);
    71     
    72     get_ans();
    73     while(T--)
    74     {
    75         int n,m;
    76         scanf("%d%d",&n,&m);
    77         int ans=mul(A[n],B[m]);
    78         printf("%d
    ",ans);
    79     }
    80     return 0;
    81 }
    View Code

    这道恶心题又卡空间 又卡时间。

    2017-02-13 13:48:22

  • 相关阅读:
    一段滚动文字的js (jQuery)
    VB ASP 使用 now() 时默认格式调整方法
    解决标题过长的CSS
    javascript Spline代码
    统计学中的几个重要的分布
    网页游戏开发秘笈 PDF扫描版
    网页设计与开发——HTML、CSS、JavaScript (王津涛) pdf扫描版
    网页设计与开发:HTML、CSS、JavaScript实例教程 (郑娅峰) pdf扫描版
    网页DIV+CSS布局和动画美化全程实例 (陈益材) 随书光盘
    实用掌中宝--HTML&CSS常用标签速查手册 PDF扫描版
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6393436.html
Copyright © 2011-2022 走看看