日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[51nod1678]lyk与gcd问题

發布時間:2025/7/14 编程问答 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [51nod1678]lyk与gcd问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這天,lyk又和gcd杠上了。 它擁有一個n個數的數列,它想實現兩種操作。

1:將 ?a?i??
?改為b。 2:給定一個數i,求所有?gcd(i,j)=1?
?時的 ?a?j??
??的總和。

Input 第一行兩個數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)。第一行兩個數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)。 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问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。