洛谷 P3312 [SDOI2014]数表
式子化出来是$\sum_{T=1}^m{\lfloor}\frac{n}{T}{\rfloor}{\lfloor}\frac{m}{T}{\rfloor}\sum_{k|T}\mu(\frac{T}{k})[\sigma(k)<=a]\sigma(k)$
如果没有a的限制的话,显然只要把后面那个sigma预处理出来
有了a的限制呢?考虑把询问按a从小到大排序,然后每次把所有满足$lasta<\sigma(k)<=nowa$(lasta指上个询问的a,nowa指当前询问的a)的加入后面那部分的贡献(开始时对于每个T预处理有哪些k满足$\sigma(k)=T$,这里就暴力枚举k使得$\sigma(k)$=当前要加入贡献的值,再暴力枚举k的倍数更新);用树状数组维护前缀和;复杂度是n*log^2+T*sqrt*log
错误记录:
1.121行<=n写成<=m;导致除以0;本地测试的时候只用了n=m的数据,所以没测出来
2.108行没规定这个<=500000
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 #define fi first 7 #define se second 8 #define mp make_pair 9 #define pb push_back 10 typedef long long ll; 11 typedef unsigned long long ull; 12 typedef pair<int,int> pii; 13 const ll N=100000; 14 const ll M=100000; 15 struct Q 16 { 17 ll n,m,a,num; 18 }q[M+100]; 19 ll qq; 20 ll ans[M+100]; 21 ll mu[N+100],len,prime[N+100]; 22 ll f1[N+100],f2[N+100],h[N+100]; 23 //分别为最小质因子的p^k,1+p^0+p^1+..+p^k,函数值 24 vector<int> dd[501000]; 25 bool nprime[N+100]; 26 bool c1(const Q &a,const Q &b) {return a.a<b.a;} 27 const ll md=1LL<<31; 28 #define lowbit(x) ((x)&(-x)) 29 ll d[N+100]; 30 void add(ll p,ll x) 31 { 32 for(;p<=N;p+=lowbit(p)) d[p]+=x; 33 } 34 ll sum(ll p) 35 { 36 ll ans=0; 37 for(;p>0;p-=lowbit(p)) ans+=d[p]; 38 return ans; 39 } 40 //ll Mod(ll a,ll b) 41 //{ 42 // if(a>=0) return a%b; 43 // else if(a%b==0) return 0; 44 // else return b+a%b; 45 //} 46 int main() 47 { 48 ll i,j,k,n,m,an; 49 mu[1]=1;h[1]=1; 50 for(i=2;i<=N;i++) 51 { 52 if(!nprime[i]) 53 { 54 prime[++len]=i;mu[i]=-1; 55 f1[i]=i;f2[i]=i+1;h[i]=i+1; 56 } 57 for(j=1;j<=len&&i*prime[j]<=N;j++) 58 { 59 nprime[i*prime[j]]=1; 60 if(i%prime[j]==0) 61 { 62 mu[i*prime[j]]=0; 63 f1[i*prime[j]]=f1[i]*prime[j]; 64 f2[i*prime[j]]=f2[i]+f1[i*prime[j]]; 65 h[i*prime[j]]=h[i]/f2[i]*f2[i*prime[j]]; 66 break; 67 } 68 else 69 { 70 mu[i*prime[j]]=-mu[i]; 71 f1[i*prime[j]]=prime[j]; 72 f2[i*prime[j]]=1+prime[j]; 73 h[i*prime[j]]=h[i]*f2[i*prime[j]]; 74 } 75 } 76 } 77 for(i=1;i<=N;i++) 78 dd[h[i]].pb(i); 79 /* 80 ll ttt=0; 81 for(i=1;i<=20000;i++) ttt=max(ttt,h[i]); 82 printf("%lld",ttt); 83 { 84 ll a,n,m,k; 85 while(1) 86 { 87 scanf("%lld%lld%lld",&n,&m,&a); 88 if(n>m) swap(n,m); 89 ll ans=0; 90 for(ll T=1;T<=m;T++) 91 { 92 ll a1=0; 93 for(k=1;k<=T;k++) 94 if(T%k==0) 95 { 96 a1+=mu[T/k]*(h[k]<=a)*h[k]; 97 } 98 ans+=(n/T)*(m/T)*a1; 99 } 100 printf("%lld\n",ans); 101 } 102 }*/ 103 scanf("%lld",&qq); 104 for(i=1;i<=qq;i++) scanf("%lld%lld%lld",&q[i].n,&q[i].m,&q[i].a),q[i].num=i; 105 sort(q+1,q+qq+1,c1); 106 for(i=1,j=0;i<=qq;i++) 107 { 108 while(j+1<=q[i].a&&j+1<=500000) 109 { 110 j++; 111 for(auto d:dd[j]) 112 { 113 for(k=d;k<=N;k+=d) 114 { 115 add(k,mu[k/d]*j); 116 } 117 } 118 } 119 if(q[i].n>q[i].m) swap(q[i].n,q[i].m); 120 n=q[i].n;m=q[i].m;an=0; 121 for(ll i=1,j;i<=n;i=j+1) 122 { 123 j=min(n/(n/i),m/(m/i)); 124 an+=(n/i)*(m/i)*(sum(j)-sum(i-1)); 125 } 126 ans[q[i].num]=an; 127 //printf("a%lld\n",an); 128 } 129 for(i=1;i<=qq;i++) printf("%lld\n",ans[i]%md); 130 return 0; 131 }