当前位置: 首页 > wzjs >正文

太原做网站软件h5游戏大全在线玩

太原做网站软件,h5游戏大全在线玩,淄博网站建设报价,北京专业设计网站给定一个长度为 n 的整数数组 nums[1..n],求有多少种划分方式可以将它划分为若干个连续区间,使得每个区间的异或值都相同。 异或的一些性质 对于二进制 0 ^ 0 0 1 ^ 0 1 0 ^ 1 1 1 ^ 1 0相同为0,不同为1 满足交换律、结合律&am…

给定一个长度为 n 的整数数组 nums[1..n],求有多少种划分方式可以将它划分为若干个连续区间,使得每个区间的异或值都相同。

异或的一些性质

对于二进制

0 ^ 0 = 0  
1 ^ 0 = 1  
0 ^ 1 = 1  
1 ^ 1 = 0

相同为0,不同为1

满足交换律、结合律:

  • a ⊕ b ⊕ c = a ⊕ c ⊕ b

  • a ⊕ a = 0

  • a ⊕ 0 = a

交换律: a ^ b = b ^ a


结合律:(a ^ b) ^ c = a ^ (b ^ c)

自反性 / 恒等律:a ^ 0 = a

自异性 / 自消律:a ^ a = 0
 

for (int i = 1; i <= n; i++) 
{b[i] = b[i - 1] ^ nums[i];
}
  • nums[i]:存储第 i 个输入的数字,数组从下标 1 开始。

  • b[i]:前缀异或数组。

  • b[i] = nums[1] ^nums[2] ... ^ nums[i]

根据自消率,当i>j时 ,b[i] ^ b[j]表示为 nums[j+1] ^ nums[j+2] ^ ... ^ nums[i]

b[j]表示为  nums[1] ^ nums[2] ^ ... ^ nums[j]

b[i]表示为  nums[1] ^ nums[2] ^ ... ^ nums[j]^ ...^ nums[i-1] ^nums[i]

枚举所有可能的目标值target

unordered_set<int> possible_targets;
for (int i = 1; i <= n; i++) {possible_targets.insert(b[i]);
}

异或区间的候选值

只考虑了前缀异或值作为 target 值候选,因为任何合法划分中,一段可能的异或值 target,至少得在某次 b[i] ^ b[j] 中出现过,而当 j == 0,它就是 b[i]

再且不计,一段合理的划分,第一段区间异或值就是b[i]

使用 unordered_set 去重,每种可能的区间异或值只遍历一次。

对每个 target 值做一次动态规划计算方案数

long long ans = 0;
for (int target : possible_targets) {vector<long long> dp_target(n + 1, 0);dp_target[0] = 1;

dp_target[i]:表示前 i 个数字中,以 i 为结尾、满足当前 target 的划分方案数

初始 dp_target[0] = 1,表示空序列有一种合法划分(啥都不划)。

在我理解应该是在序列开头划一刀

/ 1 2 1 2 1

for (int i = 1; i <= n; i++) {for (int j = 0; j < i; j++) {if (i == n && j == 0) continue; // 防止整体作为一段被重复计算//有意忽略“整段都不划分”的情况,防止它重复计数,但如果想把“整体一段”算进去,应该删掉它。if ((b[i] ^ b[j]) == target) {dp_target[i] = (dp_target[i] + dp_target[j]) % MOD;}}
}
ans = (ans + dp_target[n]) % MOD;
  • 判断是否可以将 [j+1..i] 作为一段,并且这段的异或值为 target

  • 如果是,那就可以从 dp_target[j] 转移到 dp_target[i]

  • 最终 dp_target[n] 表示从 1n 形成合法划分的方案数。

#include <bits/stdc++.h>
using namespace std;
const int MOD = 998244353;int main() {int n;cin >> n;vector<int> nums(n + 1, 0);// b[i] = nums[1] ^ nums[2] ^ ... ^ nums[i]vector<int> b(n + 1, 0); // b[i] 表示 nums[1..i] 的前缀异或vector<long long> dp(n + 1, 0); // dp[i] 表示以 i 结尾的合法划分方案数// 输入序列for (int i = 1; i <= n; i++) {cin >> nums[i];}// 计算前缀异或for (int i = 1; i <= n; i++) {b[i] = b[i - 1] ^ nums[i];}// 初始化dp[0] = 1; // 空序列有一种划分方案// 使用 unordered_set 去重 ,存储所有可能的目标 区间 异或值unordered_set<int> possible_targets;for (int i = 1; i <= n; i++) {possible_targets.insert(b[i]); // 将每个前缀异或值添加到集合中}// 对每个可能的 异或值目标 进行 DPlong long ans = 0;for (int target : possible_targets) {vector<long long> dp_target(n + 1, 0);dp_target[0] = 1;for (int i = 1; i <= n; i++) {for (int j = 0; j < i; j++) {if(i==n&&j==0)continue;//跳过了只考虑整个数组作为一段的情况 // b[i] ^ b[j] 即为 nums[j+1..i] 的异或值if ((b[i] ^ b[j]) == target) // [j+1 : i]   b[i] ^ b[j] 即为 nums[j+1..i] 的异或值{dp_target[i] = (dp_target[i] + dp_target[j]) % MOD;}}}ans = (ans + dp_target[n]) % MOD;}cout << ans << endl;//cout << ans + 1  << endl;//考虑整个数组作为一段,需要加1return 0;
}

示例;输入 5

序列 为  1 2 1 2 1

异或前缀和  b[ ]  =  [0, 1, 3, 2, 0, 1]

target = 0,1,2,3

模拟区间异或 target = 1

i15 遍历,逐步更新 dp_target[i]

dp_target[0] = 1

/ 1 2 1 2 1

[1 2 ] 1 2 1  表示为   取 [ x x x ]此区间的异或运算

j < i

i = 1:
  • 取target 为 b[1] = 1

  • 对于所有 j 使得 b[i] ^ b[j] == 1 :   [ j+1 : i ]     

    • j = 0

    • b[1] ^ b[0] = 1 ^ 0 = 1  ✅   [ 1 ]   2 1 2 1

    • 满足条件的 j,因此 dp_target[1] += dp_target[0] = 1

    • / 1 /  2 1 2 1

    • dp_target[1] = 1

i = 2
  • b[2] = 3

  • 对于所有 j 使得 b[i] ^ b[j] == 1 

    • j = 0

    • b[2] ^ b[0] = 3 ^ 0 = 3 ≠ 1   [1 2 ] 1 2 1
      不符合条件

    • j = 1

    • b[2] ^ b[1] = 3 ^ 1 = 2 ≠ 1
      没有更多满足条件的 j,因此 dp_target[2] = 0

i = 3:
  • b[3] = 2

  • 对于所有 j 使得 b[i] ^ b[j] == 1 

    • j = 0          1 2 1 ] 2 1

    • b[3] ^ b[0] = 2 ^ 0 = 2 ≠ 1

    • j = 1        1 [ 2 1 ]2  1

    • b[3] ^ b[1] = 2 ^ 1 = 3 ≠ 1

    • j = 2       1 2  [ 1 ]  2  1

    • b[3] ^ b[2] = 2 ^ 3 = 1 ✅

    • 这时,dp_target[3] += dp_target[2] = 0

    • 没有更多满足条件的 j,因此 dp_target[3] = 0

i = 4:
  • b[4] = 0

  • 对于所有 j 使得 b[i] ^ b[j] == 1 

    • j = 0             [1 2 1  2 ] 1

    • b[4] ^ b[0] = 0 ^ 0 = 0 ≠ 1

    • j = 1        1 [ 2 1  2 ]  1

    • b[4] ^ b[1] = 0 ^ 1 = 1 ✅

    • dp_target[4] += dp_target[1] = 1

    • / 1 /  2 1 2  / 1

    • j = 2     1 2 [ 1  2 ]  1

    • b[4] ^ b[2] = 0 ^ 3 = 3 ≠ 1
       

    • j = 3

    • b[4] ^ b[3] = 0 ^ 2 = 2 ≠ 3
      因此 dp_target[4] = 1

    • / 1 /  2 1 2  / 1

i = 5:
  • b[5] = 1

  • 对于所有 j 使得 b[i] ^ b[j] == 1 

    • j = 0 

    • b[5] ^ b[0] = 1 ^ 0 = 1 ✅

    • 如果考虑整段划分,也就是不划分

    • dp_target[5] += dp_target[0] = 1

    • / 1  2 1 2  1 /

    • 程序中跳过了这种情况

    • j = 1 

    • b[5] ^ b[1] = 1 ^ 1 = 0 ≠ 1

    • j = 2 

    • b[5] ^ b[2] = 1 ^ 3 = 2 ≠ 1

    • j = 3

    • b[5] ^ b[3] = 1 ^ 2 = 3 ≠ 1

    • j = 4

    • b[5] ^ b[4] = 1 ^ 0 = 1 ✅

    • 这时,dp_target[5] += dp_target[4] = 1

    • / 1  / 2 1 2 /  1 /

    • 因此 dp_target[5] = 1

当区段异或值 区间目标值 target =   1 ,存在一种划分方法 :/ 1  / 2 1 2 /  1 /

如果 考虑整段 ++ dp_target[5] = 2 就会有两种划分情况

/ 1  / 2 1 2 /  1 /

/ 1  2  1  2  1 /

示例2:

  • b[ ] = [0, 1, 3, 2, 0, 1]

  • target = 3

i = 1
  • b[1] = 1

  • 对于所有 j 使得 b[i] ^ b[j] == 3

    • b[1] ^ b[0] = 1 ^ 0 = 1 ≠ 3   [1]  2 1 2 1
      没有满足条件的 j,因此 dp_target[1] = 0

    • / 1 2 1 2 1

2. i = 2:
  • b[2] = 3

  • 对于所有 j 使得 b[i] ^ b[j] == 3

    • b[2] ^ b[0] = 3 ^ 0 = 3 ✅  [1 2] 1 2 1
      这时,dp_target[2] += dp_target[0] = 1

    •  / 1 2 /  1 2 1

    • b[2] ^ b[1] = 3 ^ 1 = 2 ≠ 3  1 [ 2 ]  1 2 1
      没有更多满足条件的 j,因此 dp_target[2] = 1

3. i = 3:
  • b[3] = 2

  • 对于所有 j 使得 b[i] ^ b[j] == 3

    • b[3] ^ b[0] = 2 ^ 0 = 2 ≠ 3   [1 2 1 ]  2 1

    • b[3] ^ b[1] = 2 ^ 1 = 3 ✅   1 [2 1] 2 1
      这时,dp_target[3] += dp_target[1] = 0

    • b[3] ^ b[2] = 2 ^ 3 = 1 ≠ 3   1 2  [1]  2 1
      没有更多满足条件的 j,因此 dp_target[3] = 0

4. i = 4:
  • b[4] = 0

  • 对于所有 j 使得 b[i] ^ b[j] == 3

    • b[4] ^ b[0] = 0 ^ 0 = 0 ≠ 3   [1 2 1   2] 1

    • b[4] ^ b[1] = 0 ^ 1 = 1 ≠ 3   [ 2 1   2] 1

    • b[4] ^ b[2] = 0 ^ 3 = 3 ✅    1 2 [ 1   2] 1
      这时,dp_target[4] += dp_target[2] = 1

    • /1 2  / 1   2 /  1

    • b[4] ^ b[3] = 0 ^ 2 = 2 ≠ 3  1 2  1  [ 2 ] 1
      因此 dp_target[4] = 1

5. i = 5:
  • b[5] = 1

  • 对于所有 j 使得 b[i] ^ b[j] == 3

    • b[5] ^ b[0] = 1 ^ 0 = 1 ≠ 3  [ 1 2 1   2  1 ]

    • / 1 2 1 2 1 /

    • 整段划分 程序出跳过

    • b[5] ^ b[1] = 1 ^ 1 = 0 ≠ 3   1[ 2 1   2  1 ]

    • b[5] ^ b[2] = 1 ^ 3 = 2 ≠ 3    1 2 [1   2  1 ]

    • b[5] ^ b[3] = 1 ^ 2 = 3 ✅    1 2 1  [ 2  1 ]
      这时,dp_target[5] += dp_target[3] = 0

    • b[5] ^ b[4] = 1 ^ 0 = 1 ≠ 3   1 2 1   2  [ 1 ]
      因此 dp_target[5] = 0

target = 3 的情况下,最终没有有效的划分方案。

18413


文章转载自:

http://F0TZWX7k.bqmhh.cn
http://Ar8q3BCL.bqmhh.cn
http://NTsSBwMV.bqmhh.cn
http://qD1PQhzD.bqmhh.cn
http://p1bNhbTN.bqmhh.cn
http://DmId8Jaq.bqmhh.cn
http://QDXC2WjO.bqmhh.cn
http://0AnC9kLf.bqmhh.cn
http://64StlPJr.bqmhh.cn
http://ZrDu0oUq.bqmhh.cn
http://KtrY8gLl.bqmhh.cn
http://YgdOWtKR.bqmhh.cn
http://kZJqF8P2.bqmhh.cn
http://w6sGNE7b.bqmhh.cn
http://1lfcrZjZ.bqmhh.cn
http://xz7rT8Jf.bqmhh.cn
http://eFBEsWUW.bqmhh.cn
http://xcizePe3.bqmhh.cn
http://WoZuOhob.bqmhh.cn
http://Gw2rVXiP.bqmhh.cn
http://DcQsn1FQ.bqmhh.cn
http://1n2gAiC8.bqmhh.cn
http://h17pPatO.bqmhh.cn
http://Wp0rcgce.bqmhh.cn
http://ALWCgFqa.bqmhh.cn
http://yBtPFYqA.bqmhh.cn
http://RBN1RTlQ.bqmhh.cn
http://VKqrPEwm.bqmhh.cn
http://IGGokEKe.bqmhh.cn
http://nnmojxdN.bqmhh.cn
http://www.dtcms.com/wzjs/681697.html

相关文章:

  • 成功的门户网站店铺代运营服务
  • 网站视频播放器用什么做的推广网站有那些
  • 衡水做网站公司网站建设设计思想
  • 沈阳建站公司模板wordpress首页错误
  • 推荐响应式网站建设天津大邱庄网站建设公司
  • 北京城乡建设部网站首页前端开发兼职的未来发展
  • 有哪些专门做校企合作的网站网站怎么建设商城
  • jquery 的网站模板鄂州网站建设哪家好
  • 用自己的电脑建设网站美橙网站维护
  • 建设银行网站连不上wordpress 技术教程
  • 重庆网站开发服务小程序后台
  • 建设网站收费标准一流的嘉兴网站建设
  • 专业做企业活动的趴网站重庆开县网站建设公司推荐
  • 不属于网站架构罗源县建设局网站
  • 网站设计提案越秀做网站
  • 月编程做网站企业网站开发实训心得
  • 网站作业手机兼职平台app排行榜前十名
  • 网新中英企业网站管理系统适合做网站的图片
  • 石材外贸网站wordpress简约企业商城
  • 定制软件开发流程怎样做网站的优化 排名
  • 公司做铸造的招聘网站都有哪些装修3d效果图怎么制作
  • 苏州乡村旅游网站建设策划书.doc灌南网页设计
  • 成都企业网站怎么做外贸邮箱用哪个比较好
  • 专业积分商城网站建设最牛论坛网站
  • 永州网站建设gwtcmswordpress搬家需要修改
  • 建设网站一般多钱网络营销推广策略包括哪些
  • 信宜做网站设置百度一下 你就知道首页
  • dtc建站服务哪个网站可以做店招
  • 网站建设流程王晴儿网络科技有限公司和科技有限公司的区别
  • 南昌做网站建设哪家好厦门百度公司