CF1416C XOR Inverse 题解
一道十分不错的分治题。
因为要进行异或操作,所以先将所有数拆成二进制数。
可以知道的是对于每一个二进制数,比较时是先比较最高位,然后接着往下面比,直到同一位上一个为
所以对于每两个不相同的二进制数,只要对它们第一个不同的地方异或
那么我们可以从
由于每一位上只有
统计完一个数位以后,会将所有数以此位上的数字分成
最后求出异或的数
递归实现,利用了分治思想,复杂度
#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
const int N=3e5+5;
int n,a[N],ans,f[N],cnt,p1[35],p2[35];
struct node
{
int data,name;
}t[N],s[N];
int cmp(node fi,node se)
{
if(fi.data==se.data)return fi.name<se.name;
return fi.data<se.data;
}
int cmp2(node fi,node se)
{
return fi.name<se.name;
}
inline int lowbit(int x)
{
return x&-x;
}
void update(int x)
{
while(x)
{
f[x]++;
x-=lowbit(x);
}
}
int search(int x)
{
int sum=0;
while(x<=cnt)
{
sum+=f[x];
x+=lowbit(x);
}
return sum;
}
void dfs(int i,int beg,int ed)
{
if(beg>=ed)return;
if(i<0)return;
bool ss=((a[beg]&(1<<i)));
int bef=beg,sum1=0,sum2=0,tot1=0,tot2=0;
for(int j=beg;j<=ed;j++)
{
int x=s[j].name;
if(((a[x]&(1<<i))>0)!=ss)
{
if(ss==1)tot1+=sum2*(j-bef);
if(ss==0)tot2+=sum1*(j-bef);
ss=((a[x]&(1<<i)));
bef=j;
}
sum1+=((a[x]&(1<<i))>0),sum2+=((a[x]&(1<<i))==0);
s[j].data=((a[x]&(1<<i))>0);
}
sort(s+beg,s+ed+1,cmp);
if(ss==1)tot1+=sum2*(ed-bef+1);
if(ss==0)tot2+=sum1*(ed-bef+1);
dfs(i-1,beg,ed-sum1);
dfs(i-1,beg+sum2,ed);
p1[i]+=tot1;
p2[i]+=tot2;
}
signed main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]),s[i].name=i;
dfs(30,1,n);
for(int i=0;i<=30;i++)if(p2[i]>p1[i])ans^=(1<<i);
for(int i=1;i<=n;i++)
{
t[i].name=i;
t[i].data=a[i]^ans;
}
sort(t+1,t+1+n,cmp);
int bef=-1;
for(int i=1;i<=n;i++)
{
if(t[i].data!=bef)cnt++;
bef=t[i].data;
t[i].data=cnt;
}
sort(t+1,t+1+n,cmp2);
int tot=0;
for(int i=1;i<=n;i++)
{
tot+=search(t[i].data+1);
update(t[i].data);
}
printf("%lld %lld",tot,ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】