E:我们从1开始考虑最大的k,从右开始到左,dp一下就好。
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef long double ld; typedef pair<int,int> pii; const int N = 1e5 + 5; const int M = 2e4 + 5; const double eps = 1e-10; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e8 #define IN_INF 0x3f3f3f3f #define dbg(ax) cout << "now this num is " << ax << endl; inline long long ADD(long long x,long long y) {return (x + y) % Mod;} inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;} inline long long MUL(long long x,long long y) {return x * y % Mod;} LL dp[N][500],sum[N];//dp[i][j] - 以i~n为起点的长度为j的最大和 int a[N]; void solve() { int n;scanf("%d",&n); for(int i = 1;i <= n;++i) scanf("%d",&a[i]),sum[i] = sum[i - 1] + a[i]; for(int i = 1;i <= n + 1;++i) { for(int j = 1;j < 500;++j) dp[i][j] = 0; } int ans = -1; for(int i = n;i >= 1;--i) { for(int j = 1;j < 500;++j) { if(i + j - 1 > n) continue; LL ma = sum[i + j - 1] - sum[i - 1]; if(dp[i + j][j - 1] > ma || j == 1) { dp[i][j] = ma; ans = max(ans,j); } dp[i][j] = max(dp[i + 1][j],dp[i][j]); } } printf("%d ",ans); } int main() { int ca;scanf("%d",&ca); while(ca--) { solve(); } //system("pause"); return 0; }
F1,F2做法一样:
我们其实只需要考虑对于i,能存入的异或值j,里<它的一个就行。
所以对于每个a[i],我们维护它覆盖的最大区间,也就是一个比他大的异或值放入就够了,然后就减小。
这样复杂度max_a[i] *max_a[i]。
注意这里G[i]要清空,才能不重复计算。
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> pii; const int N = 1e6 + 5; const int M = 2e4 + 5; const double eps = 1e-6; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 0x3f3f3f #define dbg(ax) cout << "now this num is " << ax << endl; inline long long ADD(long long x,long long y) {return (x + y) % Mod;} inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;} inline long long MUL(long long x,long long y) {return x * y % Mod;} int a[N],r[1 << 13],up = (1 << 13) - 1; bool vis[1 << 13]; vector<int> G[1 << 13]; void solve() { int n;scanf("%d",&n); for(int i = 1;i <= n;++i) scanf("%d",&a[i]); for(int i = 0;i <= up;++i) r[i] = up,G[i].push_back(0); for(int i = 1;i <= n;++i) { for(auto v : G[a[i]]) { int ma = a[i] ^ v; vis[ma] = 1; while(r[ma] > a[i]) { r[ma]--; if(r[ma] != a[i]) G[r[ma]].push_back(ma); } } G[a[i]].clear(); } int ans = 1; for(int i = 1;i <= up;++i) { ans += vis[i]; } printf("%d ",ans); for(int i = 0;i <= up;++i) { if(i == 0 || vis[i]) printf("%d ",i); } } int main() { //int ca;scanf("%d",&ca); //while(ca--) { solve(); //} // system("pause"); return 0; }