51Nod-1678 lyk与gcd

这天,lyk又和gcd杠上了。
它拥有一个n个数的数列,它想实现两种操作。
1.将ai 改为 bi
2:给定一个数i,求所有 gcd(i,j)=1gcd(i,j)=1 时的  aj  的总和。

第一行两个数n,Q(1<=n,Q<=100000)。 接下来一行n个数表示ai(1<=ai<=10^4)。 接下来Q行,每行先读入一个数A(1<=A<=2)。 若A=1,表示第一种操作,紧接着两个数i和b。(1<=i<=n,1<=b<=10^4)。 若B=2,表示第二种操作,紧接着一个数i。(1<=i<=n)。

#pragma warning(disable:4996)

#include<iostream>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_map>
#include<fstream>
#include<iomanip>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#define pb push_back
#define INF 0x3f3f3f3f
#define inf 0x7FFFFFFF
#define moD 1000000003
#define pii pair<int,string>
#define eps 1e-8
#define equals(a,b) (fabs(a-b)<eps)
#define bug puts("bug")
#define re  register
#define fi first
#define se second
typedef  long long ll;
typedef unsigned long long ull;
const ll MOD = 1e9 + 7;
const int maxn = 1e5 + 5;
const double Inf = 10000.0;
const double PI = acos(-1.0);
using namespace std;

int prime[maxn], prime_tot;
int is_prime[maxn];
int mu[maxn];
int val[maxn];
int a[100005];

void pre_calc(int lim) {
    mu[1] = 1;
    for (int i = 2; i <= lim; i++) {
        if (!is_prime[i]) {
            prime[++prime_tot] = i;
            mu[i] = -1;
        }
        for (int j = 1; j <= prime_tot; j++) {
            if (i * prime[j] > lim) break;
            is_prime[i * prime[j]] = 1;
            if (i % prime[j] == 0) {
                mu[i * prime[j]] = 0;
                break;
            }
            else mu[i * prime[j]] = -mu[i];
        }
    }
}


void init(int n) {
    for (int i = 1; i <= n; i++) {
        for (int j = i; j <= n; j += i) val[i] += a[j];
    }
}

void update(int x,int v) {
    for (int i = 1; i * i <= x; i++) {
        if (x % i == 0 && i * i != x) {
            val[i] += v - a[x];
            val[x / i] += v - a[x];
        }
        if (i * i == x) val[i] += v - a[x];
    }
    a[x] = v;
}

ll query(int x) {
    ll res = 0;
    for (int i = 1; i * i <= x; i++) if (x % i == 0 && i * i != x) res += mu[i] * val[i] + mu[x / i] * val[x / i]; else if (i * i == x)   res += mu[i] * val[i];
    //res += mu[x] * val[x];
    return res;
}



int main() {
    pre_calc(maxn -3);
    int n, q;
    scanf("%d %d", &n, &q);
    for (int i = 1; i <= n; i++) scanf("%d", a + i);
    init(n);
    while (q--) {
        int tmp;
        int x, y;
        scanf("%d", &tmp);
        if (tmp == 1) scanf("%d%d", &x, &y), update(x, y);
        else scanf("%d", &x), printf("%lld
", query(x));
        //for (int i = 0; i < n; i++) cout << val[i + 1] << endl;
    }
}
原文地址:https://www.cnblogs.com/hznumqf/p/13382704.html