第十四届浙江财经大学程序设计竞赛 B、Bazinga

题目链接:https://www.nowcoder.com/acm/contest/89/B

题目:求区间[L,R]内所有与K互质的数之积取模K;(1<= L,R<=1e18,1<=K<=1e5),最多20组测试数据;

flag:数论

**长度区间为K的里面的数取模K后,余数集合均一样,为{0,1,2,3,4,5,6……K-1};

   例: K=6, [1,6]求模6的余数集合={1,2,3,4,5,0}

                      [2,7]求模6的余数集合={2,3,4,5,0,1}

**所以我们只需要判断[K,K+L-1]内有多少个与K互质的数,用num[i]记录这些数,R-L+1=k*K+res;

  有k个区间,所以每个num[i]都应有k个,另外[K,K+res-1]内的num[i]额外加1;

 

#include <iostream>
#include <stdio.h>
#include <string.h>
#define llt long long
#include <algorithm>
using namespace std;

llt gcd(llt a,llt b){
    return (b==0)?a:gcd(b,a%b);
}

llt quick_Pow(llt x,llt K,llt a){
    if(a==0)return 1;
    if(a==1)return x%K;
    llt t=quick_Pow(x,K,a/2);

    if(a%2==0) return t*t%K;
    return t*t%K*x%K;
}
int num[100010];
int main(){
    int T;cin>>T;
    int kase=0;
    while(T--){
        llt L,R;
        llt K;
        scanf("%lld%lld%lld",&L,&R,&K);

        llt k=(R-L+1)/K;
        llt res=(R-L+1)%K;

        llt idx=-1;
        llt temp=0;
        for(llt i=0;i<K&&i<=(R-L);++i){
            llt t=(i+L)%K;
            if(gcd(t,K)==1){
                if(i<res)idx=temp;
                num[temp++]=t;
            }
        }
        llt ans=1;
        for(llt i=0;i<temp;++i){
            ans=ans*quick_Pow(num[i],K,k+(i<=idx))%K;
        }
        printf("Case #%d: %lld\n",++kase,ans);
    }
    return 0;
}

     

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值