zoukankan      html  css  js  c++  java
  • 【BZOJ】【2219】数论之神

    中国剩余定理+原根+扩展欧几里得+BSGS


      题解:http://blog.csdn.net/regina8023/article/details/44863519

      新技能get√:

     1 LL Get_yuangen(LL p,LL phi){
     2     int c=0;
     3     for(int i=2;i*i<=phi;i++)
     4         if (phi%i==0)
     5             f[++c]=i,f[++c]=phi/i;
     6     for(int g=2;;g++){
     7         int j;
     8         for(j=1;j<=c;j++) if (Pow(g,f[j],p)==1) break;
     9         if (j==c+1) return g;
    10     }
    11     return 0;
    12 }
    求原根
     1 void Split(int x){
     2     num=0;
     3     for(int i=2;i*i<=x;i++)
     4         if (x%i==0){
     5             a[++num].p=i;
     6             a[num].c=0; a[num].pc=1;
     7             while(x%i==0)
     8                 x/=i,a[num].c++,a[num].pc*=i;
     9             if (x==1) break;
    10         }
    11     if (x!=1)
    12         a[++num].p=x,a[num].pc=x,a[num].c=1;
    13 }
    分解一个数为$p_i^{a_i}$
      1 /**************************************************************
      2     Problem: 2219
      3     User: Tunix
      4     Language: C++
      5     Result: Accepted
      6     Time:288 ms
      7     Memory:5076 kb
      8 ****************************************************************/
      9  
     10 //BZOJ 2219
     11 #include<cmath>
     12 #include<map>
     13 #include<cstdio>
     14 #include<cstring>
     15 #include<cstdlib>
     16 #include<iostream>
     17 #include<algorithm>
     18 #define rep(i,n) for(int i=0;i<n;++i)
     19 #define F(i,j,n) for(int i=j;i<=n;++i)
     20 #define D(i,j,n) for(int i=j;i>=n;--i)
     21 #define pb push_back
     22 using namespace std;
     23 typedef long long LL;
     24 inline int getint(){
     25     int r=1,v=0; char ch=getchar();
     26     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
     27     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
     28     return r*v;
     29 }
     30 const int N=1e5+10;
     31 const LL inf=1e18;
     32 /*******************template********************/
     33  
     34 map<LL,LL> mp;
     35 struct data{
     36     LL p,c,pc;
     37 }a[N];
     38 int num,cnt;
     39 LL f[N];
     40 void Split(int x){
     41     num=0;
     42     for(int i=2;i*i<=x;i++)
     43         if (x%i==0){
     44             a[++num].p=i;
     45             a[num].c=0; a[num].pc=1;
     46             while(x%i==0)
     47                 x/=i,a[num].c++,a[num].pc*=i;
     48             if (x==1) break;
     49         }
     50     if (x!=1)
     51         a[++num].p=x,a[num].pc=x,a[num].c=1;
     52 }
     53 LL Pow(LL a,LL b,LL p){
     54     LL r=1;
     55     for(;b;b>>=1,a=a*a%p) if (b&1) r=r*a%p;
     56     return r;
     57 }
     58  
     59 LL Get_yuangen(LL p,LL phi){
     60     int c=0;
     61     for(int i=2;i*i<=phi;i++)
     62         if (phi%i==0)
     63             f[++c]=i,f[++c]=phi/i;
     64     for(int g=2;;g++){
     65         int j;
     66         for(j=1;j<=c;j++) if (Pow(g,f[j],p)==1) break;
     67         if (j==c+1) return g;
     68     }
     69     return 0;
     70 }
     71  
     72 void exgcd(LL a,LL b,LL &d,LL &x,LL &y){
     73     if (!b) {d=a;x=1;y=0;return;}
     74     else{exgcd(b,a%b,d,y,x); y-=x*(a/b);}
     75 }
     76  
     77 LL BSGS(LL A,LL B,LL C){
     78     int m=ceil(sqrt(C+0.5));
     79     mp.clear();
     80     LL now=1;
     81     F(i,1,m){
     82         now = now*A%C;
     83         if (!mp[now]) mp[now]=i;
     84     }
     85     mp[1]=0;
     86     A=Pow(A,m,C);
     87     now=1LL;
     88     F(i,0,m){
     89         LL d,x,y;
     90         exgcd(now,C,d,x,y);
     91         x=(x*B%C+C)%C;
     92         if (mp.count(x)) return i*m+mp[x];
     93         now=now*A%C;
     94     }
     95     return 0;
     96 }
     97  
     98 LL gcd(LL a,LL b){return b ? gcd(b,a%b) : a;}
     99  
    100 LL solve(LL A,LL B,LL k){
    101     LL phi=a[k].pc-a[k].pc/a[k].p,
    102        g=Get_yuangen(a[k].pc,phi);
    103     LL ind=BSGS(g,B,a[k].pc);
    104     LL ans=gcd(phi,A);
    105     if (ind%ans) return 0;
    106     return ans*Pow(a[k].p,cnt-cnt/A,inf);
    107 }
    108  
    109  
    110 int main(){
    111 #ifndef ONLINE_JUDGE
    112     freopen("2219.in","r",stdin);
    113     freopen("2219.out","w",stdout);
    114 #endif
    115     int T=getint();
    116     while(T--){
    117         LL A=getint(),B=getint(),k=getint();
    118         LL p=2*k+1;
    119         Split(p);
    120         LL ans=1;
    121         F(i,1,num){
    122             if (!ans) break;
    123             if (B%a[i].pc==0)
    124                 ans=ans*Pow(a[i].p,a[i].c-(a[i].c-1)/A-1,inf);
    125             else{
    126                 int b=B;
    127                 cnt=0;
    128                 while((b%a[i].p)==0){
    129                     b/=a[i].p;
    130                     a[i].pc/=a[i].p;
    131                     a[i].c--,cnt++;
    132                 }
    133                 if (cnt % A) ans=0;
    134                 else ans=ans*solve(A,b,i);
    135             }
    136         }
    137         printf("%lld
    ",ans);
    138     }
    139     return 0;
    140 }
    View Code

    2219: 数论之神

    Time Limit: 3 Sec  Memory Limit: 259 MB
    Submit: 410  Solved: 48
    [Submit][Status][Discuss]

    Description

    在 ACM_DIY群中,有一位叫做“傻崽”的同学由于在数论方面造诣很高,被称为数轮之神!对于任何数论问题,他都能瞬间秒杀!一天他在群里面问了一个神 题: 对于给定的3个非负整数 A,B,K 求出满足 (1) X^A = B(mod 2*K + 1) (2) X 在范围[0, 2K] 内的X的个数!自然数论之神是可以瞬间秒杀此题的,那么你呢?

    Input

    第一行有一个正整数T,表示接下来的数据的组数( T <= 1000) 之后对于每组数据,给出了3个整数A,B,K (1 <= A, B <= 10^9, 1 <= K <= 5 * 10^8)

    Output

    输出一行,表示答案

    Sample Input

    3
    213 46290770 80175784
    3 46290770 80175784
    3333 46290770 80175784

    Sample Output

    27
    27
    297

    HINT

     新加数组一组--2015.02.27

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    Yslow-23条规则
    ASP.Net MVC多语言
    Java笔记--反射机制
    Java笔记--常用类
    Java笔记--多线程
    Java--IO流
    Java笔记--枚举&注解
    Java笔记--泛型
    Java笔记--异常
    Java笔记--集合
  • 原文地址:https://www.cnblogs.com/Tunix/p/4547048.html
Copyright © 2011-2022 走看看