話題の顔:
要件:
まず、問題を単純化します:
これが事実であるPOI2007ZAP、クエリ
セット:
見つけることができます
そして、:
メビウス反転行為
セットアップ
あります。
問題を単純化するために、上記の式の答え
(F(TK))の後半は、ブロックで分割することができるので、全体的な時間計算量は(√N)であります
本当の問題に戻ります:
上記の意味式を考慮:I IN:1-N、J:1 - GCDの番号(i、J)= kのときに数Nの
明らかと除外を見つけることができます:
注:(M、N)を解きます=
すなわち、最終的な答えは、(B、D)-Solve(B、C-1)-Solve(-1、D)を解く+解決(-1、C-1)
コードは以下の通りであります:
書式#include <iostreamの> の#include <cstdioを> に#define int型はlong long int型 使用して 名前空間はstdを、 int型のミュウ[ 50001 ]、VIS [ 50001 ]、PRI [ 50001 ]; int型、B、C、D、K、T、CNTと、 空オイラー() { miu[1]=1; for(int i=2;i<=50000;i++) { if(!vis[i]) { ++cnt; pri[cnt]=i; miu[i]=-1; } for(int j=1;j<=cnt;j++) { if(pri[j]*i>50000) break; if(i%pri[j]==0) { vis[i*pri[j]]=1; miu[i*pri[j]]=0; break; } else { vis[i*pri[j]]=1; miu[i*pri[j]]=-miu[i]; } } } for(int i=1;i<=50000;i++) { miu[i]+=miu[i-1]; } } int Work(int n,int m) { if(n>m) swap(n,m); int X=n/k,ans=0; for(int l=1,r;l<=X;l=r+1) { r=min(n/(n/l),m/(m/l)); ans+=(miu[r]-miu[l-1])*(n/(l*k))*(m/(l*k)); } return ans; } signed main() { freopen("b.in","r",stdin); freopen("b.out","w",stdout); scanf("%lld",&t); Euler(); while(t--) { scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&k); printf(" %のLLD \ n "、ワーク(B、D)-work(A- 1、D)-work(B、C- 1)+ワーク(A- 1、C- 1 ))。 } リターン 0 ; }
エンドSahua!!!