hdu 3524 Perfect Squares 推公式求逆元

本文探讨了一个有趣的数学问题:对于给定的数字n,计算完全平方数模2^n的不同结果的数量,并提供了一种高效算法实现,包括如何处理大数运算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Perfect Squares

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 501    Accepted Submission(s): 272


Problem Description
A number x is called a perfect square if there exists an integer b 
satisfying x=b^2. There are many beautiful theorems about perfect squares in mathematics. Among which, Pythagoras Theorem is the most famous. It says that if the length of three sides of a right triangle is a, b and c respectively(a < b <c), then a^2 + b^2=c^2. 
In this problem, we also propose an interesting question about perfect squares. For a given n, we want you to calculate the number of different perfect squares mod 2^n. We call such number f(n) for brevity. For example, when n=2, the sequence of {i^2 mod 2^n} is 0, 1, 0, 1, 0……, so f(2)=2. Since f(n) may be quite large, you only need to output f(n) mod 10007.
 

Input
The first line contains a number T<=200, which indicates the number of test case.
Then it follows T lines, each line is a positive number n(0<n<2*10^9).
 

Output
For each test case, output one line containing "Case #x: y", where x is the case number (starting from 1) and y is f(x).
 

Sample Input
  
2 1 2
 

Sample Output
  
Case #1: 2 Case #2: 2

告诉一个数字n,求完全平方数摸2^n有多少不同的结果。没有说完全平方数的范围,想的话应该是循环着的,打表看一看,会发现n分奇数偶数时是有规律的。

n为奇数  2+(4^n-1)/3

n为偶数 2+2/3*(4^(n/2-1)-1)

算除法时分子很大,所以要用到逆元,求逆元的可以参看这篇 点击打开链接


#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
typedef long long ll;
const int mod=10007;

using namespace std;

ll fun(ll n,ll m)
{
    ll b=1;
    while(m)
    {
        if(m&1) b=b*n%mod;
        n=n*n%mod;
        m>>=1;
    }
    return b;
}

int main()
{
    int T;
    ll n;

    ll tmp=fun(3,mod-2);

    scanf("%d",&T);
    for(int ca=1;ca<=T;ca++)
    {
        scanf("%lld",&n);

        ll ans;
        if(n%2)
        {
            ll t=(fun(4,n/2)-1)%mod;
            ans=(2+t*tmp%mod)%mod;
        }

        else
        {
            ll t=(fun(4,n/2-1)-1)%mod;
             ans=(2+2*t*tmp%mod)%mod;
        }
        printf("Case #%d: %lld\n",ca,ans);
    }
    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值