回 帖 发 新 帖 刷新版面

主题:[讨论]很难的线性代数问题

题目描述:

输入:多组测试数据,每组一行,每组数据给出三个long long范围(1e19)内的正整数a,n,k
输出:输出a的n次方被k除的余数

样例输入:
2 32 1000
3 9 100

样例输出:
296
83

回复列表 (共21个回复)

沙发

(2的32次方)% 1000
= ((2的10次方)*(2的10次方)*(2的10次方)*2*2)%1000
= ((2的10次方)%7*(2的10次方)%7*(2的10次方)%7*2*2)%1000

因为 (2的10次方)%1000 = 24
所以上式
= ( 24的3次方 × 4 )%1000
= 296

即:
第一:a的b次方 可以化为 a平方的b/2次方(还要考虑b是奇数的情况),然后又可以再继续同样化下去
第二:(a*b)%c 可以化为 ( a%c * b%c )%c

板凳

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
long long pow(long long a,long long b){
    long long m=1;
    for(int i=1;i<=b;i++)
        m*=a;
    return m;
}
class mo{
    public:
    mo(long long a,long long n,long long k){
        r=pow(a,n)%k;
    }
    void output(){cout<<r;}
    private:
    long long r;
};


int main()
{
    ifstream infile("filename");
    if(!infile){
        cout<<"can't open file!"<<endl;
        exit(1);
    }

    long long a,n,k;
    string data;
    vector<mo>lv;
    while(getline(infile,data)){
        istringstream s(data);
        s>>a;s>>n;s>>k;
        lv.push_back(mo(a,n,k));
    }
    cout<<"output:"<<endl;
    for(vector<mo>::iterator it=lv.begin();
        it!=lv.end();++it){
        it->output();
        cout<<endl;
    }
    return 0;
}

3 楼

2楼程序编译有问题,行好为7行,8行,15行,20行,32行.

4 楼


(2的32次方)% 1000
= ((2的10次方)*(2的10次方)*(2的10次方)*2*2)%1000
= ((2的10次方)%7*(2的10次方)%7*(2的10次方)%7*2*2)%1000

第一个等号和第二个等号之间不成立:
((2的10次方)*(2的10次方)*(2的10次方)*2*2)%1000=296
 ((2的10次方)%7*(2的10次方)%7*(2的10次方)%7*2*2)%1000=32

5 楼


暑期了,应该不是求作业的吧,给你代码
[code=c]
#include <iostream>
#include <vector>
using namespace std;

const int LINE = 2;
const int MAX_LEN = 100; 
long** GetInput();
long* Calculate(long** lpArray);
void Output(long* pArray) {
    for(int i=0;i<LINE;i++) {
        cout<<pArray[i]<<endl;
    }
}

int main(int args,char** argv) {
    long** lpNumArray = NULL;
    long*  lpResultArray;
    lpNumArray = GetInput();
    lpResultArray = Calculate(lpNumArray);
    Output(lpResultArray);
    return 0;
}
long** GetInput() {
    long** lnArray;
    lnArray = new long*[LINE];
    for(int i=0;i<LINE;i++) {
        lnArray[i] = new long[3];
    }
    long lnBaseNum = 0;
    long lnPower = 0;
    long lnDivisor = 0;
    for (i=0; i<LINE; i++) {        
        cout<<"请输入数据"<<endl;
        cin>>lnBaseNum>>lnPower>>lnDivisor;
        lnArray[i][0] = lnBaseNum;
        lnArray[i][1] = lnPower;
        lnArray[i][2] = lnDivisor;
    }
    return lnArray;
}

long* Calculate(long** lpArray) {
    long lnBaseNum = 0;
    long lnPower = 0;
    long lnDivisor = 0;
    long temp = 0;
    long* lpRet = new long[LINE];
    long pBaseArray[MAX_LEN+1] = {0};//首位用来记录位数
  //  int pPowerArray[MAX_LEN] = {0};
    for(int i=0;i<LINE;i++) {
       lnBaseNum = lpArray[i][0];
       lnPower   = lpArray[i][1];
       lnDivisor = lpArray[i][2];
       int bit = 1;//底数的初始位数
       for(temp = lnBaseNum;temp != 0 && bit < MAX_LEN; bit++) {//将底数放入数组中
            pBaseArray[bit] = temp%10;
            temp /= 10;
       }
       /*指数运算*/
       pBaseArray[0] = bit - 1;
       for(long j=1;j < lnPower; j++) {     
           bit = pBaseArray[0]; 
           long carry = 0;      //进位
           int k = 1;
           for(; k <= bit; k++) {
               pBaseArray[k] *= lnBaseNum;
               pBaseArray[k] += carry;
               carry = pBaseArray[k]/10;
               pBaseArray[k] = pBaseArray[k]%10;              
              
           }
           if(carry == 0){
               k--;
           }
           for(int tmp = carry;tmp != 0 && k < MAX_LEN; k++) {//处理最后一个进位
               pBaseArray[k] = tmp%10;
               tmp /= 10;
               if(tmp == 0) {
                   k--;
               }
          }
           pBaseArray[0] = k;
       }
       /*取余运算*/
       long lntemp = 0;
       for(j=pBaseArray[0];j>0;j--) {
           lntemp = lntemp*10 + pBaseArray[j];
           lntemp %= lnDivisor;
       } 
       lpRet[i] = lntemp;       
    }    
    return lpRet;
}[/code]

6 楼

[quote]2楼程序编译有问题,行好为7行,8行,15行,20行,32行.[/quote]

你用的什么编译器啊?我用的编译器编译没有问题啊!

7 楼

我用的VC++6.0
编译结果如下:
线性代数问题.cpp(7) : error C2632: 'long' followed by 'long' is illegal
线性代数问题.cpp(8) : error C2632: 'long' followed by 'long' is illegal
线性代数问题.cpp(15) : error C2632: 'long' followed by 'long' is illegal
线性代数问题.cpp(20) : error C2632: 'long' followed by 'long' is illegal
线性代数问题.cpp(32) : error C2632: 'long' followed by 'long' is illegal
你用的啥编译器呢??

8 楼

vc++6.0有很多地方不符合c标准的
我用的是GNU GCC compiler

9 楼

VC6不光编译器内核对标准支持不好,而且很多库已经过于陈旧了(比如MFC),还是早日换掉吧

10 楼

http://blog.vckbase.com/bruceteen/archive/2010/07/15/50550.html

typedef unsigned long long T;

T MyPlus( T a, T b, T c ) // (a+b)%c
{
    if(a+b>=a) return (a+b)%c; // 不溢出
    return (a%c+b%c-c);
}

T MyMultiplies( T a, T b, T c ) // (a*b)%c
{
    if(a*b/a==b) return (a*b)%c; // 不溢出

    T s = 0;
    for( T t=a; b; t=MyPlus(t,t,c),b>>=1 )
    {
        if( (b&1) != 0 )
            s = MyPlus(s,t,c);
    }
    return s;
}

T MyPower( T a, T b, T c ) // (a^b)%c
{
    T s = 1;
    for( T t=a; b; t=MyMultiplies(t,t,c),b>>=1 )
    {
        if( (b&1) != 0 )
            s = MyMultiplies(s,t,c);
    }
    return s;
}

#include <iostream>
int main(void)
{
    std::cout << MyPower(79,13,127) << std::endl; // 26
    std::cout << MyPower(1949,1949,7) << std::endl; // 5
    std::cout << MyPower(2,666,13) << std::endl; // 12
    std::cout << MyPower(2,1000,13) << std::endl; // 3

    std::cout << MyPower(2,32,1000) << std::endl; // 296
    std::cout << MyPower(3,9,100) << std::endl; // 83

    return 0;
}

我来回复

您尚未登录,请登录后再回复。点此登录或注册