Codeforces Round #815 D1. Xor-Subsequence (easy version)

题意

一个长为 \(n(2\le n\le3\cdot10^5)\) 的序列 \(a(2\le a_i\le200)\)\(a\) 一个长为 \(m\) 的子序列表示为 \(a_{b_0},a_{b_1},...,a_{b_{p-1}}\) 。如果对于所有 \(0\le p<m-1\) ,满足 \(a_{b_p}\oplus b_{p+1}<a_{b_{p+1}}\oplus b_p\) ,则称该子序列为好的,求 \(a\) 的最长好的子序列长度。

思路

考虑设 \(f_i\) 为以 \(a_i\) 结尾的好的子序列的最大长度,注意到 \(a_{b_{p+1}}\oplus b_p\le a_{b_{p+1}}+ b_p\)\(a_{b_p}\oplus b_{p+1}\ge -a_{b_p}+ b_{p+1}\) 。于是可以推出当 \(-200+ b_{p+1}\ge200+b_p\) , 即 \(b_{p+1}\ge400+b_p\) 时,一定不满足条件,即不可能发生转移,于是直接暴力 \(\texttt{DP}\) 即可,复杂度 \(O(400n)\)

代码

#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
using LL = long long;
using LD = long double;
using ULL = unsigned long long;
using PII = pair<LL, LL>;
using TP = tuple<int, int, int>;
#define all(x) x.begin(),x.end()
#define mst(x,v) memset(x,v,sizeof(x))
#define mul(x,y) (1ll*(x)*(y)%mod)
#define mk make_pair
//#define int LL
//#define double LD
#define lc tr[x].ch[0]
#define rc tr[x].ch[1]
#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#pragma warning(disable : 4996)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const double eps = 1e-10;
const double pi = acos(-1);
const LL MOD = 1000000007;
const LL mod = 998244353;
const int maxn = 300010;

int T, N, A[maxn], f[maxn];

void solve()
{
	for (int i = 0; i < N; i++)
		f[i] = 1;
	for (int i = 0; i < N; i++)
	{
		for (int j = i + 1; j < min(i + 401, N); j++)
		{
			if ((A[i] ^ j) < (A[j] ^ i))
				f[j] = max(f[j], f[i] + 1);
		}
	}
	int ans = 0;
	for (int i = 0; i < N; i++)
		ans = max(ans, f[i]);
	cout << ans << endl;
}

int main()
{
	IOS;
	cin >> T;
	while (T--)
	{
		cin >> N;
		for (int i = 0; i < N; i++)
			cin >> A[i];
		solve();
	}

	return 0;
}
posted @ 2022-08-19 15:25  Prgl  阅读(67)  评论(0)    收藏  举报