0分求助
查看原帖
0分求助
324412
Filberte楼主2023/12/18 20:32

看了看题解,就是第一篇题解的做法。

但是WA(答案全部小了)

#include <bits/stdc++.h>
#define PLI pair<long long , int>
#define fi first
#define se second
#define ll long long
using namespace std;
const int maxq = 5e4 + 100;
const int maxn = 1e5;
const int N = 1e5 + 100;
const ll mod = (1LL << 31);
struct Qs{
    int n, m, a, num;
    friend bool operator < (Qs x, Qs y){return x.a < y.a;}
}qs[maxq];
ll t[N];
ll mu[N], sig[N];
int ex[N], pw[N];
bool vis[N];
PLI si[N];
int pri[N], idx;
void pl(ll &x, ll y){x = (x + y) % mod; }
ll mi(ll x, ll y){return ((x - y) % mod + mod) % mod;}
inline int lowbit(int x){return x & (-x);}
void add(int x, ll k){while(x <= maxn){pl(t[x], k);x += lowbit(x);}}
ll ask(int x){ll ret = 0;while(x){pl(ret, t[x]);x -= lowbit(x);}return ret;}
int Q, l;
void init(){
    mu[1] = sig[1] = 1;
    for(int i = 2;i <= maxn;i++){
        if(!vis[i]){
            pri[++idx] = i;
            mu[i] = -1;
            sig[i] = i + 1;
            ex[i] = 1, pw[i] = i;
        }
        for(int j = 1;j <= idx && pri[j] * i <= maxn;j++){
            int x = pri[j] * i;
            vis[x] = 1;
            if(pri[j] % i){
                ex[x] = 1, pw[x] = i;
                sig[x] = sig[pri[j]] * sig[i];
                mu[x] = -mu[i];
            }
            else{
                ex[x] = ex[i] + 1, pw[x] = pw[i] * pri[j];
                sig[x] = sig[pw[x]] * sig[x / pw[x]];
                mu[x] = 0;
                break;
            }
        }
    }
    for(int i = 1;i <= maxn;i++) si[i] = make_pair(sig[i], i);
    sort(si + 1, si + 1 + maxn);
}
ll ans[maxq];
int main(){
    scanf("%d",&Q);
    for(int i = 1;i <= Q;i++){scanf("%d%d%d",&qs[i].n,&qs[i].m,&qs[i].a);qs[i].num = i;}
    init();
    int id = 0;     
    sort(qs + 1,qs + 1 + Q);
    for(int i = 1;i <= Q;i++){
        while(si[id + 1].fi <= qs[i].a && id < maxn){
            int d = si[++id].se;
            for(int k = 1;k * d <= maxn;k++) add(k * d, sig[d] * mu[k]);
        }
        int n = qs[i].n, m = qs[i].m;
        if(n > m) swap(n, m);
        ll res = 0;
        for(int l = 1, r;l <= n;l = r + 1){
            r = min(n / (n / l), m / (m / l));
            pl(res, 1LL * (n / l) * (m / l) % mod * mi(ask(r) , ask(l - 1)) % mod);
        }
        ans[qs[i].num] = res;
    }
    for(int i = 1;i <= Q;i++) printf("%lld\n",ans[i]);
    return 0;
}
2023/12/18 20:32
加载中...