A本来想改到q<1e5,让你们预处理的,然后想了哈作为个逆元模板题吧= =,做不出来自行反思。

B贴个题面

FJUT2019暑假周赛三部分题解

因为只有一次机会,那么也就是两点分布期望E = p了,先说说大家的做法,先求出每个n的逆元保存,然后因为FJUT2019暑假周赛三部分题解最大只会取到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 }
View Code

相关文章: