POJ 1845 二分+素因子分解

题意:求a^b的因子的和。

对a进行素因子分解a=p1^k1*p2^k2*...*pn^kn则根据成型函数的性质有s=(1+p1+p1^2+p1^3...p1^(k1*b))*....()

等比数列直接二分求前n项和即可。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 30000
bool isprime[maxn];
int prime[maxn],nprime;
typedef long long int64;
int64 modmult(int64 a,int64 b,int64 n)//a*b%n
{
    a%=n;
    int64 ret;
    for(ret=0; b; a=(a<<1)%n,b>>=1)
        if(b&1)
            ret=(ret+a)%n;
    return ret;
}
int64 modular(int64 a,int64 b,int64 n)//renturn a^b%n
{
    int64 ans=1;
    a%=n;
    while(b)
    {
        if(b&1)
            ans=modmult(ans,a,n),b--;
        b>>=1;
        a=modmult(a,a,n);
    }
    return ans;
}
void getprime()
{
    memset(isprime,1,sizeof(isprime));
    long long i,j;
    nprime=0;
    for(i=2; i<maxn; i++)
        if(isprime[i])
        {
            prime[nprime++]=i;
            for(j=i*i; j<maxn; j+=i)
                isprime[j]=0;
        }
}
long long fac[100][2],tol;
void getfac(int n)
{
    tol=0;
    int x=n;
    memset(fac,0,sizeof(fac));
    for(int i=0; prime[i]*prime[i]<=n; i++)
        if(x%prime[i]==0)
        {
            fac[tol][0]=prime[i];
            while(x%prime[i]==0) fac[tol][1]++,x/=prime[i];
            tol++;
        }
    if(x>1)
        fac[tol][0]=x,fac[tol++][1]++;
}
long long getsum(long long a,long long k,long long m)
{
    if(k==1)
        return a%m;
    if(k&1)
        return (a+modmult(getsum(a,k/2,m),(a+modular(a,k/2+1,m))%m,m))%m;
    return modmult(getsum(a,k/2,m),1+modular(a,k/2,m),m);
}
int main()
{
    getprime();
    int a,b;
    long long ans;
    while(~scanf("%d%d",&a,&b))
    {
        if(a==1||b==0)
        {
            puts("1");
            continue;
        }
        ans=1;
        getfac(a);
        for(int i=0; i<tol; i++)
        {
            fac[i][1]*=b;
            ans=(ans*(getsum(fac[i][0],fac[i][1],9901)+1))%9901;
        }
        ans=(ans%9901+9901)%9901;
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-09-23 03:32:30

POJ 1845 二分+素因子分解的相关文章

poj 1845 Sumdiv

点击打开链接poj 1845 思路:数学+二分 分析: 1 题目要求的是A^B的所有因子的和对9901取模 2 先看几个数学定理 1:整数的唯一分解定理(如果A本身就是素数的话,那么本身就是分解式) 任意正整数都有且只有一种方式写出其素因子的乘积表达式. A = (p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)   其中pi均为素数; A^B = p1^(k1*B) * p2^(k2*B)*...* pn^(kn*B);   2:约数和公式 对于已经分解的整数A = (p

POJ 1434 二分

题意:给出离地高度b,和水箱的长宽高,给出水的容积,问装完水有多高. 二分高度,裸二分. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct cistern { double b,h,w,d; } data[50005]; int n,t; double getans(double h) { double

POJ 3525 二分+半面相交

题意:给定一个凸多边形问能包裹圆的最大半径. 将每条边向内移动距离d,知道半面相交的内核不存在,确定最大的d并且达到精度就可以了. #include<cmath> #include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int mm=111; typedef double DIY; struct point { DIY x,y; point() {}

POJ 3218 TOYS(计算几何)(二分)

TOYS:http://poj.org/problem?id=2318 大意:给你一个箱子,有n个挡板分隔成n+1部分,给你m个玩具的坐标,问每一部分有几个玩具. 思路:举对每个玩具,二分线段下标,判断玩具在线段左边还是右边,枚举后统计. 更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/ #include <map> #include <stack> #include <queue>

算法:poj 2749 &amp;amp; hdu 1815 Building roads(2-SAT + 二分,好题)

[题目大意] 有n个牛棚, 还有两个中转站S1和S2, S1和S2用一条路连接起来. 为了使得任意 牛棚两个都可以有道路联通,现在要让每个牛棚都连接一条路到S1或者S2. 有a对牛棚互相有仇恨, 所以不能让他们的路连接到同一个中转站.还有b对牛棚互相喜欢,所以他们的路必须连到同一个中专站. 道路的长度是两点的曼哈顿距离. 问最小的任意两牛棚间的距离中的最大值是多少? [思路] 两天前看了这题,当时没什么想法,今天又翻看了一下,想出来了. 每个 牛棚有可以选择S1或者S2,并且有矛盾对,是2-SA

算法:POJ 2723 Get Luffy Out(2-SAT + 二分)

[题目大意] 有2*N把不同的锁,每把锁有一个钥匙,所以共有2*N 把钥匙.把2*N把钥匙两两配 对共分为N组. 有个M层楼,每层楼有一个门,每个门上有两把锁,可能是相同的也可能是不同的. 走上某层楼之前,必须要打开这个门上的至少一个锁. 要你从每组钥匙中选择一把钥匙,然后用这 些钥匙去上这栋楼,问最多能走到几层楼? [思路] 对于每组钥匙,只能二取一,所以是2 -SAT模型. 问题是怎样找矛盾对并加边呢? 对于一个门上的两把锁,如果这两把锁的钥匙是 同一组的,那么任选一个钥匙都可以. 如果是属

算法:POJ 2296 Map Labeler(2-SAT+二分)

[题目大意] 坐标轴上有N个点,要在每个点上贴一个正方形,这个正方形的横竖边分别和x,y 轴平行,并且要使得点要么在正方形的上面那条边的中点,或者在下面那条边的中点,并且任意两个点的正 方形都不重叠(可以重边).问正方形最大边长可以多少? [思路] 可以很容易的看出,正 方形要么在点的上方,要么在下方,所以是用2-SAT来判断的,关键是加边的判断,要涉及到两个正方形的 位置的重叠关系比较麻烦. 然后二分正方形的边长即可. [代码] #include<iostream> #include<

POJ 3233 矩阵连乘+二分

这题2829MS险过..应该会有更好的方法 首先矩阵连乘这没说的 重要的是在于二分 有公式 k为奇数时 s(k)=a+(a+a^(k/2+1))*s(k/2) k为偶数时 s(k)=(1+a^(k/2))*s(k/2)  例如s(7)=a+(a+a^4)*s(3) s(6)=(1+a^3)*s(3) 有了二分的方法这题明显思路就清楚了 #include<cstdio> #include<cmath> #include<iostream> using namespace

POJ 2318 判定点在多边形内外(二分)

题意:图片是一个俯视图,按照从左到右的顺序输入边 然后输入点坐标,问从左到右的各个区域分别有多少玩具. 已知顺序只需要二分来确定区间,然后得出结果. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct point { double x,y; }; struct edge { point up,down; }