Problem descriptionteacher Mai finds that implements problems about arithmetic function can be implicitly CED to the following problem:
Maintain an array a with index from 1 to L. There are two kinds of operations:
1. Add V to ax for every X that gcd (x, n) = D.
2. Query
Inputthere are multiple test cases, terminated by a line "0 0 ".
For each test case, the first line contains two integers L, Q (1 <= L, q <= 5*10 ^ 4 ), indicating the length of the array and the number of the operations.
In following Q lines, each line indicates an operation, and the format is "1 n d v" or "2 x" (1 <= N, D, v <= 2*10 ^ 5, 1 <= x <= L ).
Outputfor each case, output "case # K:" First, where k is the case number counting from 1.
Then output the answer to each query.
Sample Input
6 41 4 1 22 51 3 3 32 30 0
Sample output
Case #1:67
Source2014 multi-university training contest 8
# Include <cstdio> # include <vector> using namespace STD; long node [50005]; int Mu [200001], prime [200001], L, Q; bool check [200001]; vector <int> fact [200001]; void Mobius () {int I, j, CNT; CNT = 0; Mu [1] = 1; for (I = 2; I <= 200000; I ++) {If (! Check [I]) {Prime [CNT ++] = I; Mu [I] =-1 ;}for (j = 0; j <CNT; j ++) {if (I * prime [J]> 200000) break; check [I * prime [J] = 1; if (I % prime [J]) mu [I * prime [J] =-mu [I]; else break ;}}for (I = 1; I <= 200000; I ++) for (j = I; j <= 200000; j + = I) fact [J]. push_back (I); // factor} void add (INT X, int v) {While (x <= L) {node [x] + = V; X + = x &-x ;}long long sum (int x) {long res = 0; while (x> 0) {res + = node [x]; x-= x &-X;} return res;} int main () {INT cases = 1, t, n, D, V, I, last; long ans, temp, lasttemp; Mobius (); While (scanf ("% d", & L, & Q) & L) {for (I = 0; I <= L; I ++) node [I] = 0; printf ("case # % d: \ n", cases ++); While (Q --) {scanf ("% d", & T); If (t = 1) {scanf ("% d", & N, & D, & V); If (N % d) continue; N/= D; for (I = 0; I <fact [N]. size (); I ++) {T = fact [N] [I]; add (T * D, Mu [T] * V );}} else {scanf ("% d", & N); ans = 0; temp = 0; for (I = 1; I <= N; I = last + 1) {last = N/(n/I); lasttemp = temp; // block acceleration temp = sum (last); ans + = N/I * (temp-lasttemp );} printf ("% i64d \ n", ANS );}}}}