hdu 3049 Data Processing(扩展欧几里德求逆元)

12 篇文章 0 订阅

Data Processing

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 980    Accepted Submission(s): 297


Problem Description
Chinachen is a football fanatic, and his favorite football club is Juventus fc. In order to buy a ticket of Juv, he finds a part-time job in Professor Qu’s lab.
And now, Chinachen have received an arduous task——Data Processing.
The data was made up with N positive integer (n1, n2, n3, … ), he may calculate the number  , you can assume  mod N =0. Because the number is too big to count, so P mod 1000003 is instead. 
Chinachen is puzzled about it, and can’t find a good method to finish the mission, so he asked you to help him.
 

Input
The first line of input is a T, indicating the test cases number.
There are two lines in each case. The first line of the case is an integer N, and N<=40000. The next line include N integer numbers n1,n2,n3… (ni<=N). 
 

Output
For each test case, print a line containing the test case number ( beginning with 1) followed by the P mod 1000003.
 

Sample Input
  
  
2 3 1 1 3 4 1 2 1 4
 

Sample Output
  
  
Case 1:4 Case 2:6
Hint
Hint: You may use “scanf” to input the data.
 
题意:求A/B%P的值。
思路:

利用P是素数所以有:

(1). A/B%P=((A%(B*P))/B)%p;

(2). A/B%P=A*(B`)%P 其中B`是B对于P的逆元

方法一:

 

#include<stdio.h>

int main() {

    int i, t, x, v = 1, n, m, ans;

    long long P, a[51000], sum;

    scanf("%d", &t);

    while (t-- && scanf("%d", &n)) {

        a[0] = 1;

        sum = 0;

        P = 1000003;

        P *= n;

        for (i = 1; i <= 40000; i++) {

            a[i] = 2 * a[i - 1];

            if (a[i] >= P)

                a[i] -= P;

        }

        for (i = 0; i < n; i++) {

            scanf("%d", &x);

            sum += a[x];

            if (sum >= P)

                sum -= P;

        }

        ans = sum / n;

        printf("Case %d:%d\n", v++, ans);

    }

}

 

方法二:

 

#include<stdio.h>

#include<math.h>

#define nmax 1000003

#define nnum 40001

int num[nnum], x, y;

int extend_gcd(int a, int b) {

    if (b == 0) {

        x = 1, y = 0;

        return a;

    }

    int d = extend_gcd(b, a % b);

    int tx = x;

    x = y;

    y = tx - a / b * y;

    return d;

}

void init() {

    int i, te;

    for (i = 0, te = 1; i < nnum; i++) {

        num[i] = te;

        te = te * 2 % nmax;

    }

}

int main() {

#ifndef ONLINE_JUDGE

    freopen("t.txt", "r", stdin);

#endif

    int t, n, i, j, k;

    long long res;

    init();

    while (scanf("%d", &t) != EOF) {

        for (i = 1; i <= t; i++) {

            scanf("%d", &n);

            for (j = 0, res = 0; j < n; j++) {

                scanf("%d", &k);

                res += num[k];

                if (res >= nmax) {

                    res -= nmax;

                }

            }

            extend_gcd(n, nmax);

            x = (x % nmax + nmax) % nmax;

            res = res * x % nmax;

            printf("Case %d:%I64d\n", i, res);

        }

    }

    return 0;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值