P7973题解
Part 1:前言
图论建模好题!
Part 2:正文
首先观察题目中所给的条件
在这里不妨令
不难发现这是一种符合条件的情况,你发现了什么?
首先摆出结论,令
考虑如何证明,若
注意到
输出的时候直接输出该并查集中的
Part 3:代码
bool DataS=0,FilE=0;
int T;
void init(){
return;
}
const int N=2e5+7,B=37;
int n;
int a[N],b[N];
int fa[N],sum[N],hib[N];
bool vis1[N],vis2[N];
int find(int i){while(i!=fa[i])i=fa[i]=fa[fa[i]];return i;}
void merge(int x,int y){x=find(x),y=find(y);if(x==y)return;fa[x]=y,sum[y]+=sum[x];}
signed main(){
if(FilE){
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
}
T=(DataS?read():1);
while(T--){
init();
n=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++){
b[i]=read();
fa[i]=i,sum[i]=b[i];
}
int bit=30;
for(int i=1;i<=bit+1;i++)fa[i+n]=i+n;
for(int i=1;i<=n;i++){
for(int j=bit,flag=1;~j;j--){
if((a[i]&(1<<j))&&flag)vis1[j]=1,flag=0,hib[i]=j;
if((!(a[i]&(1<<j)))&&(!flag))vis2[j]=1;
}
}
for(int i=1;i<=n;i++){
if(vis2[hib[i]])merge(i,hib[i]+n+1);
for(int j=hib[i],flag=1;~j;j--){
if(!(a[i]&(1<<j))&&vis1[j])merge(i,j+n+1);
}
}
for(int i=1;i<=n;i++){
int x=find(i);
printf("%lld\n",sum[x]);
}
}
return 0;
}
Part 4:后文
点赞再走吧(可怜