A本来想改到q<1e5,让你们预处理的,然后想了哈作为个逆元模板题吧= =,做不出来自行反思。
B贴个题面
因为只有一次机会,那么也就是两点分布期望E = p了,先说说大家的做法,先求出每个n的逆元保存,然后因为最大只会取到1e6,所以对0-1e6跑一遍每个数的倍数个数。复杂度O(N1/3),代码如下
1 #include <iostream> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1000000; 5 ll sum[maxn+1]; 6 ll sqr3(ll n){ 7 int l=0,r=maxn+1; 8 while(l+1<r){ 9 ll mid = (l+r)>>1; 10 if(mid*mid*mid>n) 11 r=mid; 12 else l=mid; 13 } 14 return l; 15 } 16 void exgcd(const ll a, const ll b, ll &g, ll &x, ll &y) { 17 if (!b) g = a, x = 1, y = 0; 18 else exgcd(b, a % b, g, y, x), y -= x * (a / b); 19 } 20 21 ll inv(const ll num,const ll MOD) { 22 ll g, x, y; 23 exgcd(num, MOD, g, x, y); 24 return ((x % MOD) + MOD) % MOD; 25 } 26 ll fast_mult(ll x,ll y,ll mod) { 27 ll tmp=(x*y-(ll)((long double)x/mod*y+1.0e-8)*mod); 28 return tmp<0 ? tmp+mod : tmp; 29 } 30 int main() { 31 for(ll i=1;i<=maxn;i++){ 32 sum[i]=sum[i-1]+((i+1)*(i+1)*(i+1)-1)/i-(i*i*i-1)/i; 33 } 34 int T; 35 cin>>T; 36 while(T--){ 37 ll n,mod; 38 cin>>n>>mod; 39 ll temp=sqr3(n); 40 ll ans=sum[temp-1]+n/temp-(temp*temp*temp-1)/temp; 41 ans=fast_mult(ans%mod,inv(n,mod)%mod,mod); 42 cout<<ans<<endl; 43 } 44 return 0; 45 }