求助卡常
查看原帖
求助卡常
133954
wkywkywky楼主2023/7/31 23:21

写的 O(Td(n2))O(Td(n^2)) 做法,感觉挺对

#include<bits/stdc++.h>
#define ll long long
#define lll __int128
using namespace std;
const int N=1e5+10,V=1e5,mod=1e9;
int t,cnt,s,ans,prime[N],p[N],c[N],f[N];
bitset<N>mark;
ll n,a,b;
inline void init(){
  int i,j;
  mark.set();
  for(i=2;i<=V;i++){
    if(mark[i])prime[++cnt]=i;
    for(j=1;j<=cnt&&prime[j]*i<=V;j++){
      mark[i*prime[j]]=0;
      if(i%prime[j]==0)break;
	}
  }
  return;
}
int dfs2(int st,ll m,ll d,int fl){
  if(d>b/(n/m))return 0;
  if(st==s+1){
    int res=(b/(n/m)/d)%mod;
    if(fl==-1)res=mod-res;
	return res;
  }
  int res=dfs2(st+1,m,d,fl);
  if(f[st])res=(res+dfs2(st+1,m,d*(ll)p[st],-fl))%mod;
  return res;
}
void dfs(int st,ll m){
  if(st==s+1){
    int res=(ll)((a/m)%mod)*dfs2(1,m,1,1) %mod;
    ans=(ans+res)%mod;
	return;
  }
  int i;ll v=p[st];
  f[st]=0;dfs(st+1,m);
  f[st]=1;
  if(v>a/m)return;
  for(i=1;i<=c[st];i++){
    dfs(st+1,m*v);
	if(v>a/m/(ll)p[st])break;
	v*=(ll)p[st];
  }
  return;
}
int main(){
	scanf("%d",&t);
	int i;
	init();
	while(t--){
	  scanf("%lld %lld %lld",&n,&a,&b);
	  s=0;ll val=n;
	  for(i=1;i<=cnt;i++)
	    if(val%prime[i]==0){
	      s++;p[s]=prime[i];c[s]=0;
	      while(val%(ll)prime[i]==0)val/=(ll)prime[i],c[s]++;
		}
	  dfs(1,1);
	  printf("%d\n",ans);
	  ans=0;
	}
	return 0;
}
/*
1
614889782588491410 1000000000000000000 1000000000000000000
*/
2023/7/31 23:21
加载中...