2020 CCPC 长春 K. Ragdoll(预处理+启发式合并)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020 CCPC 长春 K. Ragdoll(预处理+启发式合并)相关的知识,希望对你有一定的参考价值。
考虑 x ⊕ y = g c d ( x , y ) x\\oplus y=gcd(x,y) x⊕y=gcd(x,y)的情况应该是非常少的
不妨设 x > y x>y x>y
由于 x ⊕ y > = x − y > = g c d ( x , y ) x\\oplus y>=x-y>=gcd(x,y) x⊕y>=x−y>=gcd(x,y)
显然等号应该同时取到,得到 x ⊕ y = x − y = g c d ( x , y ) x\\oplus y=x-y=gcd(x,y) x⊕y=x−y=gcd(x,y)
枚举约数 k k k作为 g c d ( x , y ) gcd(x,y) gcd(x,y)
那么 x , y x,y x,y一定是 k k k的倍数,所以可以枚举 k k k的倍数作为 y y y
如果满足上面那个 x , y x,y x,y的关系就是合法的关系,把这些关系存起来
显然预处理这些关系的复杂度是调和级数的复杂度
那么现在只需要对一个集合维护一个桶即可
修改集合内某个点的点权,只需要枚举这个点权可能的关系即可,直接从桶里面取数
合并两个集合,使用启发式合并,小的合并到大的上面
然后桶数组也累加
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+10;
vector<int>rule[maxn];
int n,m;
int gcd(int a,int b){ return b==0?a:gcd(b,a%b); }
void init(int mx)
{
for(int i=1;i<=mx;i++)
for(int j=i;j+i<=mx;j+=i)
{
int y = j, x = j+i;
if( (x^y)==x-y && x-y==gcd(x,y) )
{
rule[x].push_back( y );
rule[y].push_back( x );
}
}
}
int fa[maxn],siz[maxn],val[maxn];
long long ans;
int find(int x){ return x==fa[x]?x:fa[x]=find(fa[x]); }
unordered_map<int,int>mp[maxn];
vector<int>vec[maxn];
void join(int x,int y)
{
int fl = find( x ), fr = find( y );
if( fl==fr ) return;
if( siz[fl]>siz[fr] ) swap(fl,fr);
// if( mp[fl].size()>mp[fr].size() ) swap(fl,fr);
for(auto v:mp[fl] )
for(auto r:rule[v.first] )
if( mp[fr].count(r) )
ans += 1ll*v.second*mp[fr][r];
for(auto v:mp[fl] ) mp[fr][v.first] += v.second;
mp[fl].clear();
siz[fr] += siz[fl], fa[fl] = fr;
}
int main()
{
init(200000);
cin >> n >> m;
for(int i=1;i<=n;i++)
{
scanf("%d",&val[i] );
fa[i] = i, siz[i] = 1, mp[i][val[i]]++;
}
while( m-- )
{
int type,x,y; scanf("%d%d%d",&type,&x,&y);
if( type==1 )
siz[x] = 1, fa[x] = x, val[x] = y, mp[x][val[x]]++;
else if( type==2 ) join(x,y);
else
{
//把节点x的权值修改为y
int zu = find( x );
mp[zu][val[x]]--;
for(auto v:rule[val[x]] ) ans -= mp[zu][v];
val[x] = y;
for(auto v:rule[val[x]] ) ans += mp[zu][v];
mp[zu][val[x]]++;
}
printf("%lld\\n",ans);
}
}
以上是关于2020 CCPC 长春 K. Ragdoll(预处理+启发式合并)的主要内容,如果未能解决你的问题,请参考以下文章
2020 ccpc长春 D. Meaningless Sequence(按位启发式合并)
2020CCPC 长春 L. Coordinate Paper(思维,构造)
2020第6届中国大学生程序设计竞赛CCPC长春站, 签到题3题