CF888 E. Maximum Subsequence 折半搜索

牛客做过类似的题,搜索对半砍,用一般的搜索树快速查询另一半有用的搜索树

时间空间大大优化。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//typedef __int128 LL;
//typedef unsigned long long ull;
//#define F first
//#define S second
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
const ld PI=acos(-1);
const ld eps=1e-9;
//unordered_map<int,int>mp;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
//#define a(i,j) a[(i)*(m+2)+(j)]  //m是矩阵的列数
//pop_back()
const int seed=131;
const int M = (1<<18)+7;
/*
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,val;}ee[M*2];
void add(int x,int y,int z){ee[++cnt].nxt=head[x],ee[cnt].to=y,ee[cnt].val=z,head[x]=cnt;}
*/
int le[M];
int ri[M];
int a[40];
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n,m;
  	cin>>n>>m;
  	for(int i=1;i<=n;i++)cin>>a[i];
  	int hf=n/2,sl=0,sr=0;
  	for(int i=0;i<1<<hf;i++)
  	{
  		ll tp=0;
  		for(int j=1;j<=hf;j++)
  			if(((i>>j-1)&1))
  				tp=(tp+a[j])%m;
		  le[++sl]=tp;
	}
    for(int i=0;i<1<<(n-hf);i++)
  	{
  		ll tp=0;
  		for(int j=1;j<=(n-hf);j++)
  			if(((i>>j-1)&1))
  				tp=(tp+a[j+hf])%m;
  		ri[++sr]=tp;
	}
	sort(ri+1,ri+1+sr);
	int ma=0;
	for(int i=1;i<=sl;i++)
	{
		int tp=lower_bound(ri+1,ri+1+sr,m-le[i])-ri;
		ma=max(ma,(ri[tp-1]+le[i])%m);
		ma=max(ma,(ri[sr]+le[i])%m);
	}
	cout<<ma<<endl;
	return 0;
}
发布了284 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/bjfu170203101/article/details/104312974