[51nod1678]lyk与gcd问题
生活随笔
收集整理的這篇文章主要介紹了
[51nod1678]lyk与gcd问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這天,lyk又和gcd杠上了。 它擁有一個n個數的數列,它想實現兩種操作。
1:將 ?a?i??
?改為b。 2:給定一個數i,求所有?gcd(i,j)=1?
?時的 ?a?j??
??的總和。
接下來一行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)。 Output 對于每個詢問輸出一行表示答案。對于每個詢問輸出一行表示答案。 Input示例 5?3 1?2?3?4?5 2?4 1?3?1 2?45?3
1?2?3?4?5
2?4
1?3?1
2?4 Output示例 9 79
7
把每個數的貢獻拆成每個質因數的貢獻,然后查詢時加加減減即可
#include <cstdio> const int maxn = 100000 + 10; bool mark[maxn] = {false}; int fr[maxn]; int pri[maxn], prn = 0; void shai(){for(int i = 2; i < maxn; i++){if(!mark[i]){fr[i] = i;pri[++prn] = i;}for(int j = 1; j <= prn && i * pri[j] < maxn; j++){mark[i * pri[j]] = true;fr[i * pri[j]] = pri[j];if(i % pri[j] == 0) break;}} } int p[maxn], pcnt, Max; inline void GetFactor(int n){pcnt = 0;int t;while(n != 1){t = fr[n];p[++pcnt] = t;while(n % t == 0) n /= t;}Max = (1 << pcnt) - 1; } int num[maxn], sum[maxn] = {0}; long long s = 0; inline void Update(int x, int y){y -= num[x];num[x] += y;for(int i = 1; i * i <= x; i++)if(x % i == 0){if(i * i == x) sum[i] += y;else{sum[i] += y;sum[x / i] += y;}}s += y; } inline long long solve(int x){GetFactor(x);long long ret = 0;for(int M, scnt, i = 0; i <= Max; i++){M = 1;scnt = 0;for(int j = 1; j <= pcnt; j++)if(i & 1 << j - 1){scnt++;M *= p[j];}if(scnt & 1) ret -= sum[M];else ret += sum[M];}return ret; } int main(){shai();int n, Q;scanf("%d %d", &n, &Q);int t;for(int i = 1; i <= n; i++){scanf("%d", num + i);s += num[i];}for(int i = 1; i <= n; i++)for(int j = i; j <= n; j += i)sum[i] += num[j];int op, x, y;while(Q--){scanf("%d %d", &op, &x);if(op == 1){scanf("%d", &y);Update(x, y);}else printf("%lld\n", solve(x));}return 0; }?
轉載于:https://www.cnblogs.com/ruoruoruo/p/7732455.html
總結
以上是生活随笔為你收集整理的[51nod1678]lyk与gcd问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spark记录-Scala基础语法
- 下一篇: input placeholder样式