CF 1365 E - Maximum Subsequence Value 思维题

题意为:选一个长度为k的子序列,计为集合s, 若s中,二进制下第i位,至少有max(1,k-2)个数是1,则获得  2^i的贡献。

求出最大贡献。(子序列集合任选)

一看这题直接莽按位从高到底枚举处理,但会发现,每一位会剩至多2个元素可变。。(即高位没选,但低位可以选)

不好处理(暴力应该可以处理,比较麻烦:先选出最高位,然后选出符合条件的次高位,然后改变可变元素剩余数量,再一次往低位枚举)

不过这题有更简单的做法:

考虑集合size>=3的情况,即集合中,二进制下,第i位都最多只能有2个0,即任意三个数在第i位的或,都必须为1。

那么任取集合中的三个数,他们或的结果,即集合的贡献(因为每一位有贡献的,任取三个或一定为1).

到这里就显然有:任选三个数,求他们的或,即贡献。枚举求出最大的即可。

(这里下标重复表示选1个或2个)

#include 
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;

int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}


ll a[M];
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n;
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i]; 
	ll mx=0;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	for(int k=1;k<=n;k++)
	{
		mx=max(mx,a[i]|a[j]|a[k]);
	}
	cout<

 

你可能感兴趣的:(CF,技巧思维题)