zoukankan      html  css  js  c++  java
  • bzoj2693--莫比乌斯反演+积性函数线性筛

    推导:

    设d=gcd(i,j)

    利用莫比乌斯函数的性质

     

    令sum(x,y)=(x*(x+1)/2)*(y*(y+1)/2)

    令T=d*t

    设f(T)=

    T可以分块。又由于μ是积性函数,积性函数的约束和仍是积性函数,所以f也是积性函数,可以O(n)线性筛求得。总时间复杂度为

    具体筛法看代码。

     代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define mod 100000009
    #define _min(a,b) a>b?b:a
    #define ll long long
    inline char nc(){
        static char buf[100000],*p1=buf,*p2=buf;
        if(p1==p2){
            p2=(p1=buf)+fread(buf,1,100000,stdin);
            if(p1==p2)return EOF;
        }
        return *p1++;
    }
    inline void read(int& x){
        char c=nc();
        for(;c<'0'||c>'9';c=nc());
        for(x=0;c>='0'&&c<='9';x=x*10+c-48,c=nc());
    }
    int len;
    char s[30];
    inline void print(ll x){
        if(!x){
            putchar('0');putchar('
    ');
            return;
        }
        for(len=0;x;x/=10)s[++len]=x%10;
        for(;len;len--)putchar(s[len]+48);
        putchar('
    ');
    }
    inline int sum(ll x,ll y){
        return (x*(x+1)/2%mod)*(y*(y+1)/2%mod)%mod;
    }
    int T,i,j,k,n,m,ma,num,p[1000001],x,a[10001],b[10001],ans;
    ll f[10000001];
    bool v[10000001];
    int main()
    {
        read(T);
        for(i=1;i<=T;i++){
            read(a[i]);read(b[i]);
            if(a[i]>b[i]){k=a[i];a[i]=b[i];b[i]=k;}
            if(a[i]>ma)ma=a[i];
        }
        f[1]=1;
        for(i=2;i<=ma;i++){
            if(!v[i]){
                p[++num]=i;
                f[i]=-(1LL*i*(i-1)%mod);
            }
            for(j=1;j<=num&&p[j]*i<=ma;j++){
                v[p[j]*i]=1;
                if(i%p[j])f[i*p[j]]=f[i]*f[p[j]]%mod;else{
                    f[i*p[j]]=f[i]*p[j]%mod;
                    break;
                }
            }
        }
        for(i=2;i<=ma;i++)f[i]=(f[i]+f[i-1])%mod;
        for(k=1;k<=T;k++){
            ans=0;
            for(i=1;i<=a[k];i=j+1){
                j=_min(a[k]/(a[k]/i),b[k]/(b[k]/i));
                ans=(ans+(f[j]-f[i-1])*sum(a[k]/i,b[k]/i)%mod)%mod;
            }
            print((ans+mod)%mod);
        }
        return 0;
    }
    bzoj2693
  • 相关阅读:
    51 Nod 1086 多重背包问题(单调队列优化)
    51 Nod 1086 多重背包问题(二进制优化)
    51 Nod 1085 01背包问题
    poj 2559 Largest Rectangle(单调栈)
    51 Nod 1089 最长回文子串(Manacher算法)
    51 Nod N的阶乘的长度 (斯特林近似)
    51 Nod 1134 最长递增子序列(经典问题回顾)
    51 Nod 1020 逆序排列
    PCA-主成分分析(Principal components analysis)
    Python中cPickle
  • 原文地址:https://www.cnblogs.com/gjghfd/p/6180859.html
Copyright © 2011-2022 走看看