zoukankan      html  css  js  c++  java
  • bzoj3283: 运算器

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 using namespace std;
      7 typedef long long int64;
      8 int Case;
      9 #define maxn 200005
     10 #define maxm 600005
     11 int now[maxn],prep[maxm];
     12 int64 val[maxm],pi,pk,t;
     13 int64 ksm(int64 x,int64 y,int64 p){
     14     if (y==0) return 1%p;
     15     if (y==1) return x%p;
     16     int64 d=ksm(x,y/2,p);
     17     if (y%2==1) return d*d%p*x%p;
     18     else return d*d%p;
     19 }
     20 int64 exgcd(int64 a,int64 b,int64 &x,int64 &y){
     21     if (b==0){
     22         x=1,y=0;
     23         return a;
     24     }
     25     int64 GCD=exgcd(b,a%b,x,y),temp;
     26     temp=x,x=y,y=temp-a/b*y;
     27     return GCD;
     28 }
     29 void insert(int x,int64 y){
     30     int pos=y%maxn;
     31     prep[x]=now[pos],now[pos]=x,val[x]=y;
     32 }
     33 int search(int64 x){
     34     int pos=x%maxn,ans=maxm*4;
     35     for (int i=now[pos];i!=-1;i=prep[i]){
     36         if (val[i]==x) ans=min(ans,i);
     37     }
     38     if (ans<maxm*4) return ans;
     39     else return -1;
     40 }
     41 int64 extanded_baby_step_gaint_step(int64 A,int64 B,int64 C){
     42     int64 tmp,temp=1,x,y,D,R,cnt=0; int pos;
     43     for (int i=0;i<32;i++){
     44         if (temp==B) return i;
     45         temp=temp*A%C;
     46     }
     47     D=1;
     48     for (temp=exgcd(A,C,x,y);temp!=1;cnt++,temp=exgcd(A,C,x,y)){
     49         if (B%temp) return -1;
     50         C/=temp,B/=temp;
     51         D=D*(A/temp)%C;
     52     }
     53     memset(now,-1,sizeof(now));
     54     R=1; tmp=ceil(sqrt(C*1.0));
     55     for (int i=0;i<tmp;i++){
     56         insert(i,R);
     57         R=R*A%C;
     58     }
     59     for (int i=0;i<tmp;i++){
     60         temp=exgcd(D,C,x,y);
     61         x=(x%C*(B/temp)%C+C)%C;
     62         pos=search(x);
     63         if (pos!=-1) return i*tmp+pos+cnt;
     64         D=D*R%C;
     65     }
     66     return -1;
     67 }
     68 int64 inv(int64 X){
     69     int64 x,y;
     70     int64 temp=exgcd(X,pk,x,y);
     71     return (x%pk+pk)%pk;
     72 }
     73 int64 work(int64 n){
     74     if (n==0) return 1LL%pk;
     75     int64 ans=1;
     76     for (int i=1;i<=pk;i++) if (i%pi) ans=ans*i%pk;
     77     ans=ksm(ans,n/pk,pk);
     78     int64 k=n%pk;
     79     for (int i=1;i<=k;i++) if (i%pi) ans=ans*i%pk;
     80     return ans*work(n/pi)%pk;
     81 }
     82 int64 calc(int64 n,int64 m){
     83     int64 a,b,c; int64 k=0;
     84     a=work(n),b=work(n-m),c=work(m);
     85     for (int i=n;i;i/=pi) k+=(i/pi);
     86     for (int i=n-m;i;i/=pi) k-=(i/pi);
     87     for (int i=m;i;i/=pi) k-=(i/pi);
     88     return 1LL*ksm(pi,k,pk)%pk*a%pk*inv(b)%pk*inv(c)%pk;
     89 }
     90 void work1(){
     91     int64 n,m,p;
     92     scanf("%lld%lld%lld",&n,&m,&p);
     93     printf("%lld
    ",ksm(n,m,p)%p);
     94 }
     95 void work2(){
     96     int64 A,B,C,ans;
     97     scanf("%lld%lld%lld",&A,&B,&C);
     98     B%=C;
     99     ans=extanded_baby_step_gaint_step(A,B,C);
    100     if (ans==-1) printf("Math Error
    ");
    101     else printf("%lld
    ",ans);
    102 }
    103 void work3(){
    104     int64 n,m,p,temp,x,y,tmp,ans=0;
    105     scanf("%lld%lld%lld",&m,&n,&p);
    106     t=p;
    107     for (int i=2;i<=sqrt(p);i++){
    108         if (t%i==0){
    109             pi=i,pk=1;
    110             while (t%i==0){
    111                 pk=pk*i;
    112                 t/=i;
    113             }
    114             temp=exgcd(p/pk,pk,x,y);
    115             tmp=calc(n,m)/temp;
    116             x=x*tmp%p*(p/pk)%p;
    117             ans=(ans+x)%p;
    118         }
    119     }
    120     if (t>1){
    121         pi=t,pk=t;
    122         temp=exgcd(p/pk,pk,x,y);
    123         tmp=calc(n,m)/temp;
    124         x=x*tmp%p*(p/pk)%p;
    125         ans=(ans+x)%p;
    126     }
    127     printf("%lld
    ",(ans%p+p)%p);
    128 }
    129 int main(){
    130     scanf("%d",&Case);
    131     for (int type;Case;Case--){
    132         scanf("%d",&type);
    133         if (type==1) work1();
    134         else if (type==2) work2();
    135         else work3();
    136     }
    137     return 0;
    138 }
    View Code

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3283

    题目大意:

    吐槽:HN2016省队集训原题,辣鸡出题人......

    做法:对于操作1,没什么好说的,直接上快速幂即可。

    对于操作2,如果p是质数,就是BSGS算法,否则,就用扩展BSGS算法;而实际上扩展BSGS可以解决p是质数,所以就不用分类讨论了。

    对于(extended)baby_step_gaint_step算法,未完待续......

    对于操作3,组合数取模,扩展lucas定理。

    对于组合数取模,未完待续......

  • 相关阅读:
    postman中 form-data、x-www-form-urlencoded、raw、binary的区别
    常见的http response
    ==容易错误的例子
    点击panel滚动条滚动到底部
    fabric实现文本聚焦、可编辑
    JSON.parse()和JSON.stringify()的使用
    centos7安装mysql
    阿里云第一次访问tomcat非常慢的解决办法
    java中的语法糖
    jvm | 基于栈的解释器执行过程
  • 原文地址:https://www.cnblogs.com/OYzx/p/5767007.html
Copyright © 2011-2022 走看看