#750 (Div. 2) F1(神奇的LIS变形

F1. Korney Korneevich and XOR (easy version)
题意:
给定一个序列 n n n 个数, 0 < = a i < = 500 0<=a_i<=500 0<=ai<=500,求序列中所有递增子序列的异或和,从小到大输出这些异或和
思路:
由于数组元素值较小,考虑对元素值进行 d p dp dp
所有元素都 < = 500 <=500 <=500,二进制表示只有 9 9 9 位,因此最大异或和为 2 9 = 512 2^9=512 29=512
考虑 f [ i ] [ j ] f[i][j] f[i][j] 表示前 i i i 个元素异或和为 j j j 时的最后一个元素的最小值
code:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define eps 1e-6
using namespace std;
const int maxn = 1e5 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
int f[2][520], op = 1;

void work()
{
	memset(f, 0x3f, sizeof(f));
	f[0][0] = 0;
	cin >> n;
	for(int i = 1; i <= n; ++i, op ^= 1){
		int x;cin >> x;
		for(int j = 0; j < 512; ++j){
			f[op][j] = f[op^1][j];
			if(f[op^1][j^x] < x) 
				f[op][j] = min(f[op][j], x);
		}
	}
	vector <int> v;
	for(int i = 0; i < 512; ++i) if(f[op^1][i] != inf)
		v.push_back(i);
	cout << v.size() << endl;
	for(auto x : v) cout << x << " ";
}

int main()
{
	ios::sync_with_stdio(0);
//	int TT;cin>>TT;while(TT--)
	work();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值