2024.2.27模拟赛T2题解

题目

有一个神奇的结论 \(\forall a<b<c , a \oplus c > min(a \oplus b,b \oplus c)\)

然后就可以写出 \(n^2\) dp,再用TRIE树优化即可

code

#include<bits/stdc++.h>
using namespace std;
#define N 200005
#define int long long
int n,k1,k2;
int a[N],fl[2];
const int mod=1e9+7;
void mo(int &x){
	if(x>=mod) x-=mod;
}
struct TRIE{
	int tot;
	int ch[N*60][2],sum[N*60];
	TRIE(){tot=1;memset(ch,0,sizeof(ch));}
	void clear(){
		while(tot) ch[tot][0]=ch[tot][1]=sum[tot]=0,tot--;
		tot=1;
	}
	void ins(int x,int y){
		int p=1;sum[1]+=y;
		for(int i=59;i>=0;i--){
			int c=(x>>i)&1;
			if(!ch[p][c]) ch[p][c]=++tot;
			p=ch[p][c],sum[p]+=y,mo(sum[p]);
		}
	}
	int find(int x,int y){
		int p=1,ans=0;
		for(int i=59;i>=0;i--){
			int c1=(x>>i)&1,c2=(y>>i)&1;
			if(!c2) ans+=sum[ch[p][c1^1]],mo(ans),p=ch[p][c1];
			else p=ch[p][c1^1];
		}
		return ans+sum[p];
	}
}T[2];
signed main(){
	//freopen("sabzeruz5.in","r",stdin);
	scanf("%lld%lld%lld",&n,&k1,&k2);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	sort(a+1,a+1+n);
	fl[0]=fl[1]=1;
	for(int i=2;i<=n;i++){
		int cnt0=T[1].find(a[i],k1);
		int cnt1=T[0].find(a[i],k2);
		//printf("%lld %lld\n",cnt0,cnt1);
		if((a[i]^a[i-1])<k1) T[0].clear();
		if((a[i]^a[i-1])<k2) T[1].clear();
		T[0].ins(a[i-1],cnt0),T[1].ins(a[i-1],cnt1);
		T[0].ins(a[i-1],fl[1]);T[1].ins(a[i-1],fl[0]);
		if((a[i]^a[i-1])<k1) fl[0]=0;
		if((a[i]^a[i-1])<k2) fl[1]=0;
	}
	printf("%lld\n",(T[0].sum[1]+T[1].sum[1])%mod);
	return 0;
}

posted @ 2024-02-27 21:56  hubingshan  阅读(33)  评论(0)    收藏  举报