【HDU1582 HDU1452 HDU1098 HDU3524 HDU1005 HDU2623 HDU2674】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sxy201658506207/article/details/84676933

题意:求2008^n的所有因子和对k取余,得到m,然后在求2008^m对给出的k取余。k是任意数(k>0)
分析:
    1. 用素因子唯一分解定理,对2008分解。
    2. 素因子求和公式之后得到m
    3. 因为要(a*b/250)%k 对于给定的k和250不确定是否互质,所以不能用求逆元的方法
    4. 公式a/b%k=a%(b*k)/b
    5. 快速幂求解最终结果.

K未知,gcd(K,250)不一定为1,不能用求逆元的方法,
但是加了一个判断就一直TLE,就这么卡时间?
TLE:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define X 10005
#define inf 0x3f3f3f3f
#define PI 3.141592653589793238462643383
int K;
const int N = 100000 + 5;
ll n,k,a,b,m,mod;
ll Pow(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
        {
            ans=(ans*a)%mod;
        }
        b>>=1;
        a=(a*a)%mod;
    }
    return ans;
}
int main()
{
    while(~scanf("%lld%lld",&n,&k))
    {
        if(n==0&&k==0)
        {
            break;
        }
        mod=k*250;
        a=Pow(2,3*n+1)-1;
        b=Pow(251,n+1)-1;
        m=(a*b)%(250*k)/250;
        mod=mod/250;
        printf("%d\n",Pow(2008,m));
    }
    return 0;
}

正解:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define X 10005
#define inf 0x3f3f3f3f
#define PI 3.141592653589793238462643383
int K,mod;
ll Pow(int a,int b)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
            ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans%mod;
}
void e_gcd(int a,int b,int &d,int &x,int &y)
{
    if(!b)
        d=a,x=1,y=0;
    else
        e_gcd(b,a%b,d,y,x),y-=a/b*x;
}
ll inv(ll a,ll m)
{
    int d,x,y;
    e_gcd(a,m,d,x,y);
    return d==1?(x+m)%m:-1;
}
int main()
{
    ios::sync_with_stdio(false);
    int N;
    while(cin>>N>>K)
    {
        if(N==K&&K==0)
            break;
        ll a,b;
        ll c=inv(250,K),m;
        if(c==-1)
        {
            mod=K*250;
            a=Pow(2,3*N+1)-1;
            b=Pow(251,N+1)-1;
            m=((a*b)%(K*250))/250;
            mod/=250;
            printf("%d\n",Pow(2008,m));
        }
        else
        {
            mod=K;
            a=Pow(2,3*N+1)-1,b=Pow(251,N+1)-1;
            m=a*b*c%K;
            cout<<Pow(2008,m)<<endl;
        }
    }
    return 0;
}

HDU1452

题意:求2004^x的所有因子和对29取余的结果。
和hdu 1852一样

  在(a/b)%p的时候
(a/b)%p=(a/b)-(a/b/p)*p
       =(a/b)-(a/(b*p)*p)
       =(a/b)-(a/(b*p)*(b*p)/b)
       =(a%(b*p))/b

                        A[i] = -(p / i) * A[p % i];
对b进行求解逆元的的充要条件是b和模数m互质gcd(b,m)=1,
设c为b的逆元:bc≡1 mod p (bc+kp=1):bc对p取余为1(p>1)
 a/b%p=a/b*1=(a/b)*bc mod p=ac mod p
解释为:除以一个数对p取模等于乘以这个数的逆元对p取模
 c=inv(b)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int mod=29;
ll Pow(int x,int n)
{
    ll ans=1;
    while(n)
    {
        if(n&1)
            ans=(ans*x)%mod;
        x=(x*x)%mod;
        n>>=1;
    }
    return ans;
}
void e_gcd(int a,int b,int &d, int &x,int &y)
{
    if(!b)
        d=a,x=1,y=0;
    else
        e_gcd(b,a%b,d,y,x),y-=a/b*x;
}
int inv(int a,int m)
{
    int d,x,y;
    e_gcd(a,m,d,x,y);
    return d==1?(x+m)%m:-1;
}
int main()
{
    ll x;
    while(scanf("%lld",&x)&&x)
    {
       ll a=Pow(2,2*x+1)-1,b=Pow(3,x+1)-1,c=Pow(167,x+1)-1;//在函数名称上找bug找了半小时pow
        cout<<(a*b*c*inv(2*166,mod))%mod<<endl;;
    }
    return 0;
}

HDU1098
 

   f(x)=5*x^13+13*x^5+k*a*x 对给定的k,找到最小的a使得任意的x都%65=0成立
  那么逆思维 对于f(1) 不管a是不是最小,那么是一定成立的,则(18+ka)%65=0
 在根据这个公式找出最小的 a ,
    这道题很有趣的思维是 关于取余的一个循环 (18%65 + ka % 65 )%65
    当 a=66的时候 又会出现 (18%65 + ka % 65 )%65 ,说明存在一个循环节
 

#include <bits/stdc++.h>
#define X 10005
#define inF 0x3f3f3f3f
#define PI 3.141592653589793238462643383
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
typedef long long ll;
const int N = 1e4;
const int Times=10;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int k;
    while(cin>>k)
    {
        int i=1;
       int  ans=18%65;
        for( i=1;i<66;++i)
        {
            if((ans+k*i)%65==0)
            {
                cout<<i<<endl;
                break;
            }
        }
        if(i==66)
            cout<<"no"<<endl;
    }
    return 0;
}

HDU3524

求:i^2%2^n有多少种不同结果
 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define X 10005
#define inf 0x3f3f3f3f
#define one 0x01
#define PI 3.141592653589793238462643383
const int N=1e4;
int mod=3*10007;
ll f[N];
ll Pow(int a,int n)
{
    ll ans=1;
    while(n)
    {
        if(n&1)
        {
            ans=ans*a%mod;
        }
        a=a*a%mod;
        n/=2;
    }
    return ans%mod;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
        int t;
        ll n;
        cin>>t;
       for(int m=1;m<=t;++m)
        {
            cin>>n;
            ll ans,te;
           if(n&1)
           {
               te=(n+1)/2;
               te--;
               ans=( (Pow(4, te )%mod+5) % mod )/ 3;
            //ans=( (Pow(4, te%(mod-1) )%mod+5) % mod )/ 3; 本来还想着用费马小定理进行降幂运算,可是3*100007不是素数
           }
           else
            {
               te=n/2-1;
                 ans=( (2*Pow(4, te )+4) % mod )/ 3;
                //ans=( (Pow(4, te%(mod-1) )%mod+5) % mod )/ 3;
            }
                cout<<"Case #"<<m<<": "<<ans<<endl;
        }
    return 0;
}
/*
  得到的前十五项是:
  2  2  3  4  7  12  23  44  87  172  343  684  1367  1824
  发现奇数项的差分别是 1  4  16  64  256  1024
  发现偶数项的差分别是 2  8  32  128 512
  奇数项 A(n)=4*A(n-1)-5 => (4^(n-1)+5)/3
  偶数项 B(n)=4*B(n-1)-4 => (2*4^(n-1)+4)/3

递推,但不是O(1)规律:
an = 2an-1 -1 奇数
an = 2an-1 -2 偶数
1
2 2
2
4 2
3
8 3
4
16 4
5
32 7
6
64 12
7
128 23
8
256 44
9
512 87
10
1024 172
11
2048 343
12
4096 684
13
8192 1367
*/
///i  0  1  2  3  4  5  6   7   8   9   10   11   12    13
///ai 1  2  2  3  4  7  12  23  44  87  172  343  684  1367
///   1  2  4  8  16 32  64  128

HDU1005 

A number sequence is defined as follows: 
f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. 
Given A, B, and n, you are to calculate the value of f(n). 
Input
The input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed. 
Output
For each test case, print the value of f(n) on a single line. 
Sample Input
1 1 3
1 2 10
0 0  0
Sample Output

5

一道矩阵快速幂的题:

递推:                     | A  1|
(fn,fn-1)=(fn-1,fn-2) |       |
                               | B  0|
                       | A  1|
最后fn=(f1,f2)*|        |     ^(n-2)
                        | B  0|
 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    int A,B;
    ll n;
    int a[100]={1,1},t;
    while(scanf("%d%d%lld",&A,&B,&n),A||B||n)
    {
        int i;
        for( i=2;i<50;++i)//这个50换成100竟然wa,不知道数据怎么设置的
        {
            a[i]=(A*a[i-1]+B*a[i-2])%7;
            if(a[i]==1&&a[i-1]==1)
            {break;}
        }
        int t=i-2+1;
        printf("%d\n",n%t==0?a[t-1]:a[n%t-1]);
    }
    return 0;
}

HDU2623 
题意:给你n和k,求

    和等于: k-1*(k/1)+(k-2*(k/2))+(k-3*(k/3))+......(k-n*(k/n))
            =kn-(1*(k/1)+(2*(k/2))+3*(k/3)+......k*(k/n))

    看 :k/1 k/2 k/3 k/4 k/5 k/6........k/n

对区间分块:
         i  1  2  3  4  5  6  7  8   .....  n
k=11 d=k/i 11  5  3  2  2  1  1  1
number=k/d  1  2  3  5  5  11 11  11 .....
number代表的就是当前d值相同的最后一个区间
 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define X 10005
#define inf 0x3f3f3f3f
#define one 0x01
#define PI 3.141592653589793238462643383
const int N=1e6;
int mod=2009;
ll f[N];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    ll n ,k;
    while(cin>>n>>k)
    {
        ll sum=n*k;
        ll len=min(n,k);///n<k 算到n   k<n 算到k
        ll ans=0;
        for(int i=1;i<=len;++i)
        {
            ll d=k/i;
            ll number=k/d;
            if(number>len)
                number=len;
           // cout<<i<<' '<<d<<' '<<number<<' '<<(d*(i+number)*(number-i+1)/2)<<endl;
            ans+=(d*(i+number)*(number-i+1)/2);
            i=number;
        }
        cout<<sum-ans<<endl;
    }
    return 0;
}

HDU2136
题目大意:求一个数的最大素数因子在素数序列中排第几。
总结:Everybody knows any number can be combined by the prime number.每个数都可以由一个素数结合起来(素数本身由自己和1组成,质数则可由一个素数和其他的数乘积得到
每个数都可以由一个若干个素数组成
T:

#include<bits/stdc++.h>
const int N=1000000;
using namespace std;
  int primer[N],po[N],cnt=0;
int main()
{

    po[cnt++]=1;
    for(int i=2;i<N;++i)
    {
        if(!primer[i])
        {
            po[cnt++]=i;
            for(int j=i*2;j<N;j+=i)
            {
                primer[j]=1;
            }
        }
    }

   int n;
    while(~scanf("%d",&n))
        {
        for(int i=n;i>=0;--i)
        {
            if(po[i]<=n)//po[n]>n
            {
                if(n%po[i]==0)
                {
                    printf("%d\n",i);
                    break;
                }
            }
        }
    }
    return 0;
}

正解:
 

#include<bits/stdc++.h>
const int N=1e6;
using namespace std;
 int primer[N],cnt=0;
int main()
{
    for(int i=2;i<N;++i)
    {
        if(!primer[i])
        {
            primer[i]=++cnt;
            for(int j=2*i;j<N;j+=i)
            {
                primer[j]=cnt;
            }
        }
    }
    int n;
    while(~scanf("%d",&n))
    {
        printf("%d\n",primer[n]);
    }
    return 0;
}

HDU 2674 
计算的是N!%2009,0<=N<=10^9。

蒙,打个表,n>40 都是0

正解:
考察的是 mod=2009的质因数
2009=7*7*41 所以n=7的时候就差个41想乘取模就为0 所以到41取模就为0

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define X 10005
#define inf 0x3f3f3f3f
#define one 0x01
#define PI 3.141592653589793238462643383
const int N=1e6;
int mod=2009;
ll f[N];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    f[0]=1;
    for(int i=1;i<=40;++i)
    {
        f[i]=(i*f[i-1])%mod;
        // cout<<i<<' '<<f[i]<<endl;
    }
       // cout<<41*245%2009<<endl;
       ll n;
    while(cin>>n)
    {
        if(n<41)
            cout<<f[n]<<endl;
        else
            cout<<0<<endl;
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/sxy201658506207/article/details/84676933
hdu