BZOJ 2956: 模积和

题解:

注意看题!!!!!

注意p不是质数

注意随时取模

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mm=19940417;

int n,m;
long long ans=0;
long long inv=0;
long long phi;

long long Ksm(long long a,int p){
    long long ret=1;
    for(;p;p>>=1,a=a*a%mm){
        if(p&1)ret=ret*a%mm;
    }
    return ret;
}

long long Sol(int n){
    long long ret=1LL*n*n%mm;
    int last;
    for(int i=1;i<=n;i=last+1){
        last=n/(n/i);
        ret=(ret-1LL*(i+last)*(last-i+1)/2%mm*(n/i)%mm+mm)%mm;
    }
    return ret;
}

long long Cal(int l,int r){
    long long ret=0;
    ret=1LL*r*(r+1)%mm*(r+r+1)%mm*inv%mm;
    --l;
    ret=(ret-1LL*l*(l+1)%mm*(l+l+1)%mm*inv%mm+mm)%mm;
    return ret;
}




int main(){
    phi=mm;
    int x=mm;
    for(int i=2;i*i<=x;++i){
        if(x%i==0){
            phi=phi/i*(i-1);
        }
        while(x%i==0)x/=i;
    }
    if(x>1)phi=phi/x*(x-1);
    inv=Ksm(6*1LL,phi-1);
    
    cin>>n>>m;
    if(n>m)swap(n,m);
    ans=Sol(n)*Sol(m)%mm;
    
    ans=(ans-1LL*n*m%mm*n%mm+mm)%mm;
    
    int last;
    for(int i=1;i<=n;i=last+1){
        
        last=(n/(n/i));
        ans=(ans+1LL*(i+last)*(last-i+1)/2%mm*(n/i)%mm*m%mm)%mm;
    }
    
    for(int i=1;i<=n;i=last+1){
        last=min(n,m/(m/i));
        ans=(ans+1LL*(i+last)*(last-i+1)/2%mm*(m/i)%mm*n%mm)%mm;
    }
    for(int i=1;i<=n;i=last+1){
        last=min(n/(n/i),m/(m/i));
        ans=(ans-1LL*(n/i)*(m/i)%mm*Cal(i,last)%mm+mm)%mm;
    }
    cout<<ans<<endl;
    return 0;
}
自己还是太辣鸡了
原文地址:https://www.cnblogs.com/zzyer/p/8611126.html