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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

51Nod 1439 - 互质对(容斥+莫比乌斯函数)

發布時間:2024/9/5 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 51Nod 1439 - 互质对(容斥+莫比乌斯函数) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接 https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1439

【題目描述】
有n個數字,a[1],a[2],…,a[n]。有一個集合,剛開始集合為空。然后有一種操作每次向集合中加入一個數字或者刪除一個數字。每次操作給出一個下標x(1 ≤ x ≤ n),如果a[x]已經在集合中,那么就刪除a[x],否則就加入a[x]。

問每次操作之后集合中互質的數字有多少對。

注意,集合中可以有重復的數字,兩個數字不同當且僅當他們的下標不同。

比如a[1]=a[2]=1。那么經過兩次操作1,2之后,集合之后存在兩個1,里面有一對互質。

Input
單組測試數據。
第一行包含兩個整數n 和 q (1 ≤ n, q ≤ 2 × 10^5)。表示數字的種類和查詢數目。
第二行有n個以空格分開的整數a[1],a[2],…,a[n] (1 ≤ a[i] ≤ 5 × 10^5),分別表示n個數字。
接下來q行,每行一個整數x(1 ≤ x ≤ n),表示每次操作的下標。

Output
對于每一個查詢,輸出當前集合中互質的數字有多少對。
Input示例
樣例輸入1
5 6
1 2 3 4 6
1
2
3
4
5
1
樣例輸入2
2 3
1 1
1
2
1
Output示例
樣例輸出1
0
1
3
5
6
2
樣例輸出2
0
1
0
【思路】
如果已經知道現在集合中有多少對互質對,現在新加入一個元素x,那么只要計算這個xx和集合中的所有元素能夠形成多少個互質對,加到答案中去,刪除元素同理. 問題就是要計算一個數字和一堆數字會組成多少互質對,反過來考慮問題,也可以計算組成非互質對的個數然后用集合的大小減去就得到互質對的個數
那非互質對怎么計算,假設新加入一個整數xx,原來集合中有一個元素uu,如果(x,u)(x,u)不是互質對,那么gcd(x,u)!=1gcd(x,u)!=1 同時 gcd(x,u)gcd(x,u)的值一定是xx的一個因子,這里我們就可以遍歷xx的每一個大于1的因子,然后用容斥原理來計算了,具體怎么算這里舉個例子,比如現在集合SS中已經有了5個元素,新加入一個x=24x=24,我們遍歷xx的所有大于1的因子2,3,4,6,8,12,242,3,4,6,8,12,24,如果集合SS中有約數為2的數,那么xx就會和SS中每一個有約數2的數產生一個非互質對,同理其它的約數3,4,6,8...3,4,6,8...都是,但是會算重,如果已經計算過SS中有約數為2的個數和約數為3的個數,那么其實已經計算過了SS中有約數為6的個數了,而且還算了兩回,所以這里就要減掉了.而對于4,8,12,244,8,12,24而言,它們都已經在計算2,32,3的時候算過了,可以發現這里新產生的互質對的對數為5?S2?S3+S65?S中有約數2的個數?S中有約數3的個數+S中有約數6的個數 對于每個約數而言,前面的系數就是莫比烏斯函數的函數值
代碼中先把每個數的約數都預處理出來,然后在主函數中直接枚舉,要用輸入掛才能卡過去

#include<bits/stdc++.h> namespace fastIO {#define BUF_SIZE 100000//fread -> read1,bool IOerror = 0;inline char nc() {static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;if(p1 == pend) {p1 = buf;pend = buf + fread(buf, 1, BUF_SIZE, stdin);if(pend == p1) {IOerror = 1;return -1;}}return *p1++;}inline bool blank(char ch) {return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';}inline void read(int &x) {char ch;while(blank(ch = nc()));if(IOerror)return;for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');}#undef BUF_SIZE };using namespace std; using namespace fastIO; typedef long long ll;const int maxa=200005; const int maxn=500005;bool vis[maxn]; int prim[maxn]; int mu[maxn]; int cnt;void get_mu(int n){mu[1]=1;for(int i=2;i<=n;i++){if(!vis[i]){prim[++cnt]=i;mu[i]=-1;}for(int j=1;j<=cnt && prim[j]*i<=n;j++){vis[prim[j]*i]=1;if(i%prim[j]==0) break;else mu[i*prim[j]]=-mu[i];}} }int n,q; int a[maxa]; bool in[maxa]; int c[maxn]; vector<int> g[maxn];void init(){get_mu(maxn-1);for(int i=1;i<maxn;++i){for(int j=i;j<maxn;j+=i){g[j].push_back(i);}} }int main(){init();read(n);read(q);for(int i=1;i<=n;++i) read(a[i]);ll ans=0;while(q--){int id,x;read(id);x=a[id];if(!in[id]){int num=g[x].size();for(int i=0;i<num;++i){int u=g[x][i];ans+=mu[u]*c[u];++c[u];}}else{int num=g[x].size();for(int i=0;i<num;++i){int u=g[x][i];--c[u];ans-=mu[u]*c[u];}}in[id]=!in[id];printf("%lld\n",ans);}return 0; }

轉載于:https://www.cnblogs.com/wafish/p/10465182.html

總結

以上是生活随笔為你收集整理的51Nod 1439 - 互质对(容斥+莫比乌斯函数)的全部內容,希望文章能夠幫你解決所遇到的問題。

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