2020 ccpc 长春 K - Ragdoll
K - Ragdoll
Once there was a lovely ragdoll cat, named Little Zara, who liked trees and math. One day she met the doge Adam. Adam had just planted some trees each consisting of only one node. The nodes were numbered from 1 to n, and the i-th node was assigned a value ai. Adam liked pairing tree nodes, but he disliked some node pairs. A pair of nodes ( was considered bad if i and j were in the same tree and gcd, where gcd denotes the greatest common divisor (GCD) of integers x and y, and ⊕ denotes the bitwise XOR operation. Adam wondered how many bad pairs there were in his forest.
Zara was good at solving problems about trees and math, so she could answer Adam's question in a short time. However, Adam was so naughty a dog that he would repeatedly change the forest slightly and ask Zara his question again after the change.
The changes Adam might make are listed here:
- Adam plants a new tree with only one node numbered x and assigned a value v.
- Adam uses magic to merge the tree containing the node x and the one containing the node y. If x and y are in the same tree before the operation, the magic fails and has no effect.
- Adam changes the value of node x to v.
Now you are expected to help Zara answer all questions Adam asked, in order that they could sing and dance together happily.
Input
The first line contains two integers n and m (1, 1), representing the number of nodes in the original forest and the number of changes Adam would make, respectively.
The next line contains n integers , (1).
Each of the next m lines describes a change Adam made, starting with an integer t (1) representing the type of the change.
- If t=1, it will be followed by two integers x and v (n<x≤n+m, 1). It is guaranteed that x's are distinct in all changes of the first type.
- If t=2, it will be followed by two integers x and y (1). It is guaranteed that the node x and y already exist in the forest.
- If t=3, it will be followed by two integers x and v. (1, 1). It is guaranteed that the node x already exists in the forest.
Output
For each change Adam made, print one line with a single integer, representing the number of bad pairs in the forest after the change.
Example
Input 1
3 6
3 2 1
2 1 2
1 5 3
2 1 2
2 3 2
2 5 1
3 3 2
Output 1
1
1
1
1
2
4
Input 2
10 6
6 6 4 7 7 4 6 4 6 5
2 5 1
2 10 7
2 8 7
2 7 2
2 6 2
2 9 1
Output 2
1
1
3
4
7
8
题目描述:问在同一个集合中,对任意i,j,有a[i]^a[j]==gcd(a[i],a[j])的对数,求所有集合的对数和。
操作1:以x建立一个新集合,且a[x]=y;
操作2:把x和y所在的集合合并;
操作3:把a[x]变成y;
转载:https://blog.csdn.net/qq_45458915/article/details/109605372?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160559725819724835851365%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=160559725819724835851365&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-29-109605372.pc_first_rank_v2_rank_v28&utm_term=2020ccpc%E9%95%BF%E6%98%A5&spm=1018.2118.3001.4449
代码:
#include<bits/stdc++.h> #include<ext/rope> //#include<hash_map> #define sd(x) scanf("%d",&x) #define lsd(x) scanf("%lld",&x) #define ms(x,y) memset(x,y,sizeof x) #define fu(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define all(a) a.begin(),a.end() using namespace std; using namespace __gnu_cxx; typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef pair<int,int> P; const int N=5e5+99; const int mod=1e9+7; const int INF=1e9+7; const double pi=acos(-1); int fa[N],sz[N],n,m,x,y,a[N]; vector<int> p[N]; unordered_map<int,ll> mp[N]; //mp[x][a[x]]=cnt void init() { fu(i,1,N-1) fa[i]=i,sz[i]=1; fu(g,1,N-1) { for(int x=g*2;x<N;x+=g) { int y=(x^g); if(__gcd(x,y)==g) p[x].push_back(y); } } } int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); } int main() { init(); sd(n);sd(m); fu(i,1,n) sd(a[i]),mp[i][a[i]]++; ll ans=0; while(m--) { int t;sd(t); if(t==1) { sd(x);lsd(a[x]); mp[x][a[x]]++; } else if(t==2) { sd(x);sd(y); int fx=find(x),fy=find(y); if(fx==fy) { printf("%lld\n",ans); continue; } if(sz[fx]>sz[fy]) swap(fx,fy); for(auto xx:mp[fx]) { for(auto pairx:p[xx.first])//枚举每个匹配关系 { if(mp[fy].count(pairx))//在fy集合中 ans+=xx.second*mp[fy][pairx]; } } for(auto xx:mp[fx]) mp[fy][xx.first]+=xx.second; mp[fx].clear(); fa[fx]=fy,sz[fy]+=sz[fx]; } else { sd(x);sd(y); int f=find(x); for(auto pairx:p[a[x]]) { if(mp[f].count(pairx)) ans-=mp[f][pairx]; } mp[f][a[x]]--; mp[f][y]++; a[x]=y; for(auto pairx:p[y]) { if(mp[f].count(pairx)) ans+=mp[f][pairx]; } } printf("%lld\n",ans); } return 0; }
浙公网安备 33010602011771号