2 条题解

  • 0
    @ 2025-12-4 10:55:14
    • 考虑前缀和优化
    • 两假设我们要求 a[j..i]a[j..i] 的异或和
    • 那么只需要用 a[1..(j1)]a[1..(j-1)]a[1..i]a[1..i] 的前缀异或和,再取异或就好
    • 时间复杂度:O(n×log(n))O(n \times log(n))
    • 期望得分:100100
    #include <bits/stdc++.h>
    using namespace std;
    
    using i64 = long long;
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0); cout.tie(0);
    
    	int n, m;
    	cin >> n >> m;
    	vector<int> a(n + 1);
    	for (int i = 1; i <= n; i++) cin >> a[i];
    
    	// dp(i): 前 i 个数最多能选多少区间
    	vector<int> dp(n + 1, 0);
    	map<int, int> q; q[0] = 0;
    	int now = 0;
    	for (int i = 1; i <= n; i++) {
    		dp[i] = dp[i - 1];  // 不用 a[i]
    		now ^= a[i];        // 前缀异或
    
    		// 假设 a[j..i] 的异或和为 m
    		// 那么 a[1..(j - 1)] 和 a[1..i] 的异或前缀和就是 m
    		if (q.count(now ^ m)) dp[i] = max(dp[i], dp[q[now ^ m]] + 1);
    		q[now] = i;
    	}
    	cout << dp[n] << '\n';
    
    	return 0;
    }
    
    • 0
      @ 2025-12-4 10:44:20
      • dp(i)dp(i):前 ii 个数最多能选多少区间
      • 时间复杂度:O(n2)O(n^2)
      • 期望得分:6060
      #include <bits/stdc++.h>
      using namespace std;
      
      using i64 = long long;
      
      int main() {
      	ios::sync_with_stdio(false);
      	cin.tie(0); cout.tie(0);
      
      	int n, m;
      	cin >> n >> m;
      	vector<int> a(n + 1);
      	for (int i = 1; i <= n; i++) cin >> a[i];
      
      	// dp(i): 前 i 个数最多能选多少区间
      	vector<int> dp(n + 1, 0);
      	for (int i = 1; i <= n; i++) {
      		// 不用 a[i]
      		dp[i] = dp[i - 1];
      
      		// 用 a[i], 枚举包含 a[i] 的区间
      		for (int j = i, now = 0; j >= 1; j--) {
      			now ^= a[j];
      			if (now == m) {
      				// a[j..i] 的异或和为 m
      				dp[i] = max(dp[i], dp[j - 1] + 1);
      			}
      		}
      	}
      	cout << dp[n] << '\n';
      
      	return 0;
      }
      
      • 1

      信息

      ID
      199
      时间
      1000ms
      内存
      512MiB
      难度
      5
      标签
      递交数
      27
      已通过
      13
      上传者