专栏文章

题解:P8766 [蓝桥杯 2021 国 AB] 异或三角

P8766题解参与者 2已保存评论 2

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
2 条
当前快照
1 份
快照标识符
@mipoew67
此快照首次捕获于
2025/12/03 15:19
3 个月前
此快照最后确认于
2025/12/03 15:19
3 个月前
查看原文
一道有难度的数位 DP,感觉比一些紫题还难。

思路

  • 可以发现 a,b,ca,b,c 没有顺序,所以令 a>ba>b 并且 a>ca>c 最后答案乘三即可。
  • 引用状压的思想,用二进制表示状态,其中令 11 表示 a>ba>b 然后 1010 表示 a>ca>c 接着 100100 表示 a,b,ca,b,c 构成三角形。
  • 其中关于证明 a,b,ca,b,c 是否可以构成三角形,理由如下:根据三角形性质得 a<b+ca<b + c 其中 aa 是最大的,所以 a=bca=b \oplus cbc=b+cb \oplus c=b + c 易证 b,cb,c 的二进制数至少有一位同为一,所以只要 b,cb,c 至少有一位同为一就是三角形。

Code

CPP
#include<bits/stdc++.h>
#define int long long
#define f(i,j,k) for(int i=j;i<=k;i++)
#define F(i,j,k) for(int i=j;i>=k;i--)
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
inline void write(int x){
	if(x<0) {x=~(x-1); putchar('-');}
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
int T=read(),dp[2][40][8],loc[40],cnt;
inline int dfs(int pos,int vis,int st){
	if(!pos) return st==7;
	if(dp[vis][pos][st]!=-1) return dp[vis][pos][st];
	int nex=vis?loc[pos]:1,res=0;
	res+=dfs(pos-1,vis&&nex==0,st);
	if((st&1)&&(st>>1&1)) res+=dfs(pos-1,vis&&nex==0,st|4);
	if(nex==1) res+=dfs(pos-1,vis,st|1)+dfs(pos-1,vis,st|2);
	return dp[vis][pos][st]=res;
}
inline void get(){
	int x=read(); cnt=0; memset(dp,-1,sizeof(dp));
	while(x) loc[++cnt]=x&1,x>>=1;
	write(dfs(cnt,1,0)*3); puts("");
}
inline void work(){while(T--) get();}
signed main(){work();return !!!!!("YZren");}

评论

2 条评论,欢迎与作者交流。

正在加载评论...