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\n", query(x)); //for (int i = 0; i < n; i++) cout << val[i + 1] << endl; } }