ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

一个筛子(例一)

2020-09-23 22:35:40  阅读:143  来源: 互联网

标签:筛子 一个 argT ch define 例一 ans include mod


一个筛子(例一)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <iterator>
#include <utility>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
#define mp make_pair
#define fi first
#define se second
#define All(x) (x).begin(), (x).end()
#define Y1 "YES"
#define N1 "NO"
#define ENDL '\n'
#define count2(x) __builtin_popcount(x)
#define countleadingzero(x) __builtin_clz(x)
inline ll read() {  // not solve LLONG_MIN LMAX=9,223,372,036,854,775,807
    ll s = 0, w = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')
            w = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return s * w;
}
struct ygsz{
	typedef __int128_t returnT;
	typedef long long argT;
	typedef unsigned int sqargT;
	static constexpr argT maxm=1e5+10;
	sqargT primelist[maxm],pcnt=0;
	bool isnprime[maxm];
	double inv[maxm];
	static constexpr argT mod = 1e9+7;
	inline argT fpowll(argT a,argT b,argT p){//a^b mod p;
		assert(p!=0);
		argT ans=1%p,base=a%p;
		for(;b>0;b/=2){
			if(b&1)ans=(returnT)ans*base%p;
			base=(returnT)base*base%p;
		}
		return ans;
	}
	const argT inv2=fpowll(2,mod-2,mod);
	inline void init(){
	    constexpr argT m=maxm-1;
	//    constexpr argT mz=m/log10(m);
	    primelist[++pcnt]=2;
	    for(argT i = 1;i <= m; ++i)
	        inv[i] = 1.0 / i;
	    // i*i may overflow
	    for(argT j = 4; j <=m; j+=2)
	    isnprime[j] = true;
	    for (argT i = 3; i <= m; i+=2){
	        if(!isnprime[i]){
	            primelist[++pcnt]=i;
	            // i*i may overflow
	            for(argT j = i * i; j <=m; j+=i)
	            isnprime[j] = true;
	        }
	    }
	    return ;
	}
	argT a[maxm];
	returnT b[maxm];//质数前缀和
	argT s1[maxm],s2[maxm];//质数个数前缀和 
	inline argT f(const argT x){
		return x;
	}
	//int ppt=0;
	inline argT n34divlognsieve(const argT n) {
	    if (n <= 1) return 0;
	    const sqargT m = sqrt(n);
	    constexpr double eps = 1e-7;
	    for (sqargT i = 2; i <= m; ++i)    
	        a[i] = (a[i - 1] + i)%mod,s1[i] = i - 1;
	    for (sqargT i = 1; i <= m; ++i) {  
	        returnT sum_n = n / i;
	        b[i] = ((sum_n + sum_n * sum_n) *inv2 - 1)%mod;
	        s2[i] = sum_n - 1;
	    }
	    const sqargT pt=upper_bound(primelist+1,primelist+1+pcnt,m)-primelist;
	    for (sqargT r=1;r<pt;++r) {
	        const sqargT prime=primelist[r];
	        const argT t = a[prime - 1];
	        const argT s = s1[prime - 1];
	        const double invprime=inv[prime];
	        const sqargT limmp = m * invprime + eps;
	        for (sqargT i = 1; i <= limmp; ++i){
	        	b[i] =(b[i]- (b[i * prime] - t) * prime)%mod; 
	        	s2[i] =(s2[i] - (s2[i *prime] - s))%mod;
				s2[i] =(s2[i] + mod)%mod;
			}
	            
	        const sqargT limnpp = n / prime / prime;
	        const argT limnp = n / prime;
	        const sqargT lim2=min(limnpp,m);
	        double *ptr=&inv[limmp + 1];
	        for (sqargT i = limmp + 1; i <= lim2 ; ++i,++ptr) {
	        	b[i] =(b[i]- (a[(unsigned int)(limnp * (*ptr)  + eps)] - t) * prime)%mod;
	        	s2[i] =(s2[i]- (s1[(unsigned int)(limnp * (*ptr)  + eps)] - s) )%mod;
	        	s2[i] =(s2[i]+mod)%mod;
			}
	            
	        const argT limpp = prime * prime;
	        for (argT i = m; i >= limpp; --i){
	        	a[i] =(a[i]- (a[(unsigned int)(i * invprime + eps)] - t) * prime)%mod;
	        	s1[i] =(s1[i] - (s1[(unsigned int)(i * invprime + eps)] - s))%mod;
	        	s1[i] =(s1[i]+mod)%mod;
			}
	    }
	    for (argT i = 1; i <= m; ++i){
	    	a[i]=(a[i]-s1[i]+(i>=2)*2+mod)%mod;
	    	b[i]=(b[i]-s2[i]+(n/i>=2)*2+mod)%mod;
		}
	    return b[1];
	}
	argT n;
	returnT work(argT pos,argT res,argT rem){
		argT t = (rem <= sqrt(n)? a[rem]: b[n/rem]);
		returnT ans = (res * (t -a[primelist[pos-1]])%mod)%mod;
		for(argT i = pos; i <= pcnt; ++i){
			if(primelist[i]*primelist[i]>rem)return ans;
			for(argT t=primelist[i],js=1;t<=rem;t*=primelist[i],++js){
				if(t*primelist[i]<rem)ans+=work(i+1,res*(primelist[i]^js)%mod,rem/t);
				if(js>=2)ans=(ans+res*(primelist[i]^js)%mod )%mod;
			}
		}
		return ans;
	}	
}P;

int main() {
    P.init();
    ll n=read();
    P.n=n;
   	P.n34divlognsieve(n);
    cout<<(int)P.work(1,1,n)+1;
    return 0;
}

标签:筛子,一个,argT,ch,define,例一,ans,include,mod
来源: https://www.cnblogs.com/passguan/p/13721498.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有