zoukankan      html  css  js  c++  java
  • light oj 1236 分解质因数

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70017#problem/H

    题意:求满足1<=i<=j<=n且lcm(i,j)=n的pair<i,j>的数目

    一开始我是这么想的:

    既然lcm(i,j)=n,

    那么n=x*i=y*j,且x和y一定互质。

    若i和j固定了,那么x和y也固定了。

    那么问题就转化成求n的约数中互质的pair的数目

    由唯一分解定理,设n有p个质因数,每个质因数的幂是a[i]

    设x包括了其中的m个质因子,那么这m个y中一定就没有了

    然后用排列组合可以YY出一个奇怪的式子

    但是这种方法实际上并不好用。。。。

    因为每个质因数可以取1....a[i]个。。。

    最后式子中还会a要求a[]的全排列之类的。。。【什么鬼

    然后就很复杂啦

    换种思路:由lcm(A,B)=M

    因为M是A和B的公倍数,所以M的质因数是A和B的并集

    设分解质因数之后:

    A=x^a1+y^a2+z^a3+......

    B=x^b1+y^b2+z^b3+......

    M=x^c1+y^c2+z^c3+......

    因为M是A和B的最小公倍数,

    所以对每个质因数都会有max(ai , bi)=ci

    比如设ci=2,那么就有以下几种情况:

    ai=2 , bi=2    ai=2 , bi=1    ai=2 , bi=0

    ai=1 , bi=2    ai=0 , bi=2

    用这个性质就可以推出公式啦:

    对于每一个质因子,可能的情况有2*ci+1种

    而不同质因子又是相互独立事件,所以直接套乘法原理,得ans=(2*c1+1)*(2*c2+1)*......*(2*ci+1)

    但是中间会有重复的情况(用iPad或草稿纸YY一下很容易看出来的),所以还要ans=(ans-1)/2+1

    注意注意注意:::

    因为n很大,所以要注意数据类型。特别是中间变量的数据类型

    【被坑了2h  QAQ】

      1 #include <cstdlib>
      2 #include <cctype>
      3 #include <cstring>
      4 #include <cstdio>
      5 #include <cmath>
      6 #include <algorithm>
      7 #include <vector>
      8 #include <string>
      9 #include <iostream>
     10 #include <map>
     11 #include <set>
     12 #include <queue>
     13 #include <stack>
     14 #include <bitset>
     15 #include <list>
     16 #include <cassert>
     17 #include <complex>
     18 using namespace std;
     19 #define rep(i,a,n) for (int i=a;i<n;i++)
     20 #define per(i,a,n) for (int i=n-1;i>=a;i--)
     21 #define all(x) (x).begin(),(x).end()
     22 //#define fi first
     23 #define se second
     24 #define SZ(x) ((int)(x).size())
     25 #define TWO(x) (1<<(x))
     26 #define TWOL(x) (1ll<<(x))
     27 #define clr(a) memset(a,0,sizeof(a))
     28 #define POSIN(x,y) (0<=(x)&&(x)<n&&0<=(y)&&(y)<m)
     29 typedef vector<int> VI;
     30 typedef vector<string> VS;
     31 typedef vector<double> VD;
     32 typedef long long ll;
     33 typedef long double LD;
     34 typedef pair<int,int> PII;
     35 typedef pair<ll,ll> PLL;
     36 typedef vector<ll> VL;
     37 typedef vector<PII> VPII;
     38 typedef complex<double> CD;
     39 const int inf=0x20202020;
     40 const ll mod=1000000007;
     41 const double eps=1e-9;
     42 
     43 ll powmod(ll a,ll b)             //return (a*b)%mod
     44 {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
     45 ll powmod(ll a,ll b,ll mod)     //return (a*b)%mod
     46 {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
     47 ll gcd(ll a,ll b)                 //return gcd(a,b)
     48 { return b?gcd(b,a%b):a;}
     49 // head
     50 
     51 namespace Factor {
     52     const int N=1010000;
     53     ll C,fac[10010],n,mut,a[1001000];
     54     int T,cnt,i,l,prime[N],p[N],psize,_cnt;
     55     ll _e[100],_pr[100];
     56     vector<ll> d;
     57 
     58     inline ll mul(ll a,ll b,ll p) {     //return (a*b)%p
     59         if (p<=1000000000) return a*b%p;
     60         else if (p<=1000000000000ll) return (((a*(b>>20)%p)<<20)+(a*(b&((1<<20)-1))))%p;
     61         else {
     62             ll d=(ll)floor(a*(long double)b/p+0.5);
     63             ll ret=(a*b-d*p)%p;
     64             if (ret<0) ret+=p;
     65             return ret;
     66         }
     67     }
     68 
     69     void prime_table(){     //prime[1..tot]: prime[i]=ith prime
     70         int i,j,tot,t1;
     71         for (i=1;i<=psize;i++) p[i]=i;
     72         for (i=2,tot=0;i<=psize;i++){
     73             if (p[i]==i) prime[++tot]=i;
     74             for (j=1;j<=tot && (t1=prime[j]*i)<=psize;j++){
     75                 p[t1]=prime[j];
     76                 if (i%prime[j]==0) break;
     77             }
     78         }
     79     }
     80 
     81     void init(int ps) {                 //initial
     82         psize=ps;
     83         prime_table();
     84     }
     85 
     86     ll powl(ll a,ll n,ll p) {           //return (a^n)%p
     87         ll ans=1;
     88         for (;n;n>>=1) {
     89             if (n&1) ans=mul(ans,a,p);
     90             a=mul(a,a,p);
     91         }
     92         return ans;
     93     }
     94 
     95     bool witness(ll a,ll n) {
     96         int t=0;
     97         ll u=n-1;
     98         for (;~u&1;u>>=1) t++;
     99         ll x=powl(a,u,n),_x=0;
    100         for (;t;t--) {
    101             _x=mul(x,x,n);
    102             if (_x==1 && x!=1 && x!=n-1) return 1;
    103             x=_x;
    104         }
    105         return _x!=1;
    106     }
    107 
    108     bool miller(ll n) {
    109         if (n<2) return 0;
    110         if (n<=psize) return p[n]==n;
    111         if (~n&1) return 0;
    112         for (int j=0;j<=7;j++) if (witness(rand()%(n-1)+1,n)) return 0;
    113         return 1;
    114     }
    115 
    116     ll gcd(ll a,ll b) {
    117         ll ret=1;
    118         while (a!=0) {
    119             if ((~a&1) && (~b&1)) ret<<=1,a>>=1,b>>=1;
    120             else if (~a&1) a>>=1; else if (~b&1) b>>=1;
    121             else {
    122                 if (a<b) swap(a,b);
    123                 a-=b;
    124             }
    125         }
    126         return ret*b;
    127     }
    128 
    129     ll rho(ll n) {
    130         for (;;) {
    131             ll X=rand()%n,Y,Z,T=1,*lY=a,*lX=lY;
    132             int tmp=20;
    133             C=rand()%10+3;
    134             X=mul(X,X,n)+C;*(lY++)=X;lX++;
    135             Y=mul(X,X,n)+C;*(lY++)=Y;
    136             for(;X!=Y;) {
    137                 ll t=X-Y+n;
    138                 Z=mul(T,t,n);
    139                 if(Z==0) return gcd(T,n);
    140                 tmp--;
    141                 if (tmp==0) {
    142                     tmp=20;
    143                     Z=gcd(Z,n);
    144                     if (Z!=1 && Z!=n) return Z;
    145                 }
    146                 T=Z;
    147                 Y=*(lY++)=mul(Y,Y,n)+C;
    148                 Y=*(lY++)=mul(Y,Y,n)+C;
    149                 X=*(lX++);
    150             }
    151         }
    152     }
    153 
    154     void _factor(ll n) {
    155         for (int i=0;i<cnt;i++) {
    156             if (n%fac[i]==0) n/=fac[i],fac[cnt++]=fac[i];}
    157         if (n<=psize) {
    158             for (;n!=1;n/=p[n]) fac[cnt++]=p[n];
    159             return;
    160         }
    161         if (miller(n)) fac[cnt++]=n;
    162         else {
    163             ll x=rho(n);
    164             _factor(x);_factor(n/x);
    165         }
    166     }
    167 
    168     void dfs(ll x,int dep) {
    169         if (dep==_cnt) d.push_back(x);
    170         else {
    171             dfs(x,dep+1);
    172             for (int i=1;i<=_e[dep];i++) dfs(x*=_pr[dep],dep+1);
    173         }
    174     }
    175 
    176     void norm() {
    177         sort(fac,fac+cnt);
    178         _cnt=0;
    179         rep(i,0,cnt) if (i==0||fac[i]!=fac[i-1]) _pr[_cnt]=fac[i],_e[_cnt++]=1;
    180             else _e[_cnt-1]++;
    181     }
    182 
    183     vector<ll> getd() {
    184         d.clear();
    185         dfs(1,0);
    186         return d;
    187     }
    188 
    189     vector<ll> factor(ll n) {       //return all factors of n        cnt:the number of factors
    190         cnt=0;
    191         _factor(n);
    192         norm();
    193         return getd();
    194     }
    195 
    196     vector<PLL> factorG(ll n) {
    197         cnt=0;
    198         _factor(n);
    199         norm();
    200         vector<PLL> d;
    201         rep(i,0,_cnt) d.push_back(make_pair(_pr[i],_e[i]));
    202         return d;
    203     }
    204 
    205     bool is_primitive(ll a,ll p) {
    206         assert(miller(p));
    207         vector<PLL> D=factorG(p-1);
    208         rep(i,0,SZ(D)) if (powmod(a,(p-1)/D[i].first,p)==1) return 0;
    209         return 1;
    210     }
    211 }
    212 
    213 int TTT;
    214 ll N;
    215 int main()
    216 {
    217     scanf("%d",&TTT);
    218     Factor::init(200000);
    219   //Factor::init(10000000);
    220     for (int TT=1;TT<=TTT;TT++)
    221     {
    222         cin>>N;
    223         //scanf("%lld",&N);
    224         ll ans=1;
    225         vector<PLL> p=Factor::factorG(N);
    226         for (vector<PLL>::iterator i=p.begin();i!=p.end();i++)
    227         {
    228             ll tm=i->first;
    229             int POW=0;
    230             ll T=N;
    231             while (T%tm==0)
    232             {
    233                 POW++;
    234                 T=T/tm;
    235             }
    236             //cout<<"-->  "<<tm<<" - "<<POW<<endl;
    237             ans=ans*(1+2*POW);
    238         }
    239         ans=(ans-1)/2+1;
    240         cout<<"Case "<<TT<<": "<<ans<<endl;
    241         //printf("Case %d: %lld
    ",TT,ans);
    242         //printf("Case %d: %lld
    ",TT,ans);
    243     }
    244 }
    View Code
  • 相关阅读:
    14_java之变量|参数|返回值|修饰符
    NYOJ 202 红黑树 (二叉树)
    NYOJ 138 找球号(二) (哈希)
    NYOJ 136 等式 (哈希)
    NYOJ 133 子序列 (离散化)
    NYOJ 129 树的判定 (并查集)
    NYOJ 117 求逆序数 (树状数组)
    NYOJ 93 汉诺塔 (数学)
    HDU 2050 折线分割平面 (数学)
    天梯赛L2-008 最长对称子串 (字符串处理)
  • 原文地址:https://www.cnblogs.com/pdev/p/4340916.html
Copyright © 2011-2022 走看看