http://www.lydsy.com/JudgeOnline/problem.php?id=3529
Let me worship for a while popoqqq thank you.
#include <cstdio> #include <iostream> #include <cstring> #include <climits> #include <
Algorithm> using namespace std;
const int MAXN = 100000;
const int MAXT = 20000;
BOOL NOTPRIME[MAXN+10];
int prime[maxn+10], mu[maxn+10], sum[maxn+10], Max; struct Fs{int val, fval;}
F[MAXN+10];
BOOL CMPV (fs A, FS B) {return a.val < b.val;} void Init () {mu[1] = 1;
int tmp;
for (int i=2;i<=max;i++) {if (!notprime[i]) {Mu[i] =-1;
Prime[++prime[0]] = i;
} for (int j=1;j<=prime[0]&& (tmp=prime[j]*i) <=max;j++) {notprime[tmp] = true;
if (i%prime[j] = = 0) {Mu[tmp] = 0;
Break
} Mu[tmp] =-mu[i];
}} for (int i=1;i<=max;i++) {f[i].fval = i;
for (int j=i;j<=max;j+=i) F[j].val + = i;
}} int Lowbit (int u) {return (u& (-U));} void Add (int p, int v) {while (P<=max) {Sum[p] + = V;
P+=lowbit (P);
}} int query (int p) {int ret = 0;
while (P > 0) {ret + = sum[p];
P-= Lowbit (p);
} return ret;
} void Solve (int n, int m, int &ans) {ans = 0;
for (int i=1;i<=n;i++) {int last = min ((n/(n/i)), (m/(m/i)));
Ans + = (n/i) * (m/i) * (Query (last)-query (i-1));
Ans &= Int_max;
i = last; }} struct Task{int n, M, A, ans, id;}
TS[MAXT+10];
BOOL Cmpt (Task A, task B) {return A.A < B.A;} bool Cmpid (Task A, task B) {return a.id < b.id;} int main () {int T;
scanf ("%d", &t);
for (int i=1;i<=t;i++) {scanf ("%d%d%d", &TS[I].N, &TS[I].M, &TS[I].A);
if (TS[I].N > TS[I].M) Swap (TS[I].N, TS[I].M);
max = max (max, TS[I].N);
Ts[i].id = i;
} Init ();
Sort (f+1, F+1+max, CMPV);
Sort (ts+1, ts+1+t, cmpt);
int pos = 0; for (int i=1;i<=t;i++) {while (F[pos+1].val <= ts[i].a && pos+1 ≪= Max) {pos++;
for (int j=f[pos].fval;j<=max;j+=f[pos].fval) Add (J, F[pos].val * Mu[j/f[pos].fval]);
} Solve (TS[I].N, TS[I].M, Ts[i].ans);
} sort (ts+1, ts+1+t, cmpid);
for (int i=1;i<=t;i++) printf ("%d\n", Ts[i].ans);
return 0;
}