Alex decided to try his luck in TV shows. He once went to the quiz named "What's That Word?!". After perfectly answering the questions "How is a pseudonym commonly referred to in the Internet?" ("Um... a nick?"), "After which famous inventor we name the unit of the magnetic field strength?" ("Um... Nikola Tesla?") and "Which rock band performs "How You Remind Me"?" ("Um... Nickelback?"), he decided to apply to a little bit more difficult TV show: "What's in This Multiset?!".c++
The rules of this TV show are as follows: there are ngit
multisets numbered from 1 to n. Each of them is initially empty. Then, qapp
events happen; each of them is in one of the four possible types:ide
- 1 x v — set the x
-th multiset to a singleton {v}ui
- 2 x y z — set the x
- 3 x y z — set the x
- 4 x v — the participant is asked how many times number v
- only.
Note, that xthis
, y and z described above are not necessarily different. In events of types 2 and 3, the sum or the product is computed first, and then the assignment is performed.spa
Alex is confused by the complicated rules of the show. Can you help him answer the requests of the 4code
-th type?orm
InputThe first line contains two integers nblog
and q (1≤n≤105, 1≤q) — the number of multisets and the number of events.
Each of the following q
lines describes next event in the format given in statement. It's guaranteed that 1≤x,y and 1≤v≤7000always holds.
It's guaranteed that there will be at least one event of the 4
-th type.
OutputPrint a string which consists of digits 0
and 1 only, and has length equal to the number of events of the 4-th type. The i-th digit of the string should be equal to the answer for the i-th query of the 4-th type.
Example4 13 1 1 1 1 2 4 1 3 6 4 4 4 1 4 4 2 2 1 2 2 3 3 4 4 4 4 3 2 2 3 4 2 1 4 2 2 4 2 3 4 2 4
010101
Here is how the multisets look in the example test after each of the events; i
is the number of queries processed so far:
題意:
n個可重集,有Q次操做
1 u v 表示將第u個可重集的元素置爲1個v
2 u a b 表示將第u個可重集置爲第a個可重集和第b個可重集的並集
3 u a b 表示將第u個可重集置爲第a個可重集的每一個元素和第b個可重集的每一個元素的gcd的並集
4 u v 表示求在第u個可重集中元素v的出現次數是奇數仍是偶數
n<=1e5 Q<=1e6 1<=v<=7000
思路:因爲是隻要求奇數仍是偶數,咱們整個過程只須要保存0和1便可,咱們用莫比烏斯來求是否存在一個gcd,即保存當前集合是因子的奇偶性。那麼對於2和3,咱們能夠直接操做(分別是^ &)了。
假設咱們知道了因子的數量的奇偶性,假設保存在s[]裏面。 vis[gcd]=mu(d/gcd)*s[d];因此對於每一個gcd,咱們預處理出mu(d/gcd)!=0的位置d,保存到b[]裏面。
因爲只求奇偶,1和-1的效果等效,結果和s[x]*b[y]的1的數量奇偶相同;
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=100010; const int maxm=7001; bitset<maxm>s[maxn],b[maxm]; int mu[maxm],p[maxm],cnt;bool vis[maxm]; vector<int>G[maxm]; void init() { mu[1]=1; rep(i,2,maxm-1){ if(!vis[i]) p[++cnt]=i,mu[i]=-1; rep(j,1,cnt){ if(i*p[j]>=maxm) break; vis[i*p[j]]=1; if(!(i%p[j])) {mu[i*p[j]]=0; break;} mu[i*p[j]]=-mu[i]; } } rep(i,1,maxm-1) for(int j=i,k=1;j<=maxm-1;j+=i,k++){ G[j].push_back(i); if(mu[k]!=0) b[i][j]=1; } } int main() { int N,M,opt,x,y,z; init(); scanf("%d%d",&N,&M); while(M--){ scanf("%d",&opt); if(opt==1){ scanf("%d%d",&x,&y); s[x].reset(); rep(i,0,G[y].size()-1) s[x][G[y][i]]=s[x][G[y][i]]^1; } else if(opt==2){ scanf("%d%d%d",&x,&y,&z); s[x]=s[y]^s[z]; } else if(opt==3){ scanf("%d%d%d",&x,&y,&z); s[x]=s[y]&s[z]; } else { scanf("%d%d",&x,&y); if((s[x]&b[y]).count()&1) putchar('1'); else putchar('0'); } } return 0; }