CF2066C Bitwise Slides

CF2066C Bitwise Slides_第1张图片

题目大意

给定一个长度为 n 的数组 a,以及三个初始值为 0 数 P,Q,R。进行 n 次操作,第 i 次操作中,选择 P,Q,R 中的一个数,变成与 a[i] 的异或和,且每次操作后 P,Q,R 中至少有两个数相等。求出合法的可能操作且对 1e9 + 7 取模。

题目分析

设数组 p 为数组 a 的前缀异或和,则由异或的性质可知:p[i] = p[i-1]^a[i]。又因为, P,Q,R 的初始值为0且每次操作都将其中的一个数更新为其与 a[i] 的异或和,故进行了 i 次操作后,PQR = p[i]。又因为最少有两个值相等,根据异或的性质 a ^ a = 0 ,假设 Q 与 R 相同,则 P = p[i]。因为 P,Q,R 三者是等价的,可以相互转换,故可以得出结论:执行 i 次操作后 P,Q,R 中必然有一个值为 p[i]

用(P,Q,R)表示三者的值,设 P 的值为 p[i] , dp[i,x] 为执行 i 次操作后相同的两数为 x 的总可能数,讨论状态转移方程:

    一.进行i次操作后,为 (p[i],p[i],p[i]) :

            1.由(p[i-1],p[i],p[i])或(p[i],p[i-1],p[i])或(p[i],p[i],p[i-1])转移得到,对于每种可能只有一种固定的转移方式(即只能对不为 p[i] 的数操作),故 dp[i,p[i]] = dp[i - 1,p[i]]

    二.进行 i 次操作后,为 (p[i],p[i-1],p[i-1]):

            1.由(p[i-1],p[i-1],p[i-1])转移得到,有三种可能(只能对p[i-1]操作,p[i-1]有三个),故 dp[i,p[i - 1]] = dp[i - 1,p[i - 1]] * 3;

            2.由(p[i],p[i],p[i-1])转移得到,有两种可能(只能对p[i]操作,p[i]有两个),故 dp[i,p[i - 1]] = dp[i - 1,p[i]] * 2;

    三.进行i次操作后,为(p[i],x,x)(x为不为p[i-1]和p[i]的任意值):

            1.由(p[i-1],x,x)转移得到,只有一种可能(只能对p[i-1]操作),故 dp[i,x] = dp[i - 1,x];

综上所述,第 i - 1 次状态转移到第 i 次状态的状态转移方程只与第 i - 1 次状态下相同两数的值有关,故可以用滚动数组优化。重新设 dp[i] 为相同两数为 i 的总可能数,则执行一次操作后的状态转移方程为:

    dp[p[i - 1]] = dp[p[i - 1]] * 3 + dp[p[i]] * 2

同时注意到,数值很大,不能直接建立数组进行存储,可以使用map建立映射关系,降低空间复杂度。

最后,代码实现,欢迎各位大佬指教

#include 
#include 
using namespace std;
long long t, a[200010] = {}, n, ans = 0, mod = 1e9 + 7;
map<long long, long long>dp;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> t;
    while (t--) {
        cin >> n;
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            a[i] ^= a[i - 1];//维护前缀异或和
        }
        dp.clear();
        dp[0] = 1;//初始情况下P,Q,R全为0,所以dp[0]的值为1
        for (int i = 1; i <= n; i++) {
            dp[a[i - 1]] = (dp[a[i - 1]] * 3 % mod + dp[a[i]] * 2 % mod) % mod;//dp[i]中的i为P,Q,R中相同两个数的值,dp[i]的值为可能性
        }
        ans = 0;
        for (auto [u, v] : dp) {
            ans = (ans + v) % mod;//答案为map中可能性的和
        }
        cout << ans << '\n';
    }
}

你可能感兴趣的:(算法,动态规划)