bzoj5092: [Lydsy1711月赛]分割序列

【题解】

  理解得迷迷糊糊。。。

  一些准备操作就不说了吧。。

  首先对于当前的第i个数,贪心思想按二进制位从高到低考虑。

  若当前第j位是1,不管异或0还是1,这一位的贡献肯定是1<<j,不考虑??

  对于当前位是0的情况,你只要考虑是否有数 包含 前面几位高位的被异或出来的1 的情况下,当前位也是1,那么就异或上当前的1,加上当前的1的贡献,也就是答案加上2<<j。

  这里有个细节,处理第j位的时候,先不用管低位是否被影响到(可以思考一下)。

  主要是考虑怎么求出是否有满足条件的数。

  这个只要预处理出一个数组f[sta],表示状态集包含sta的出现最早的位置,对于之后关于第i位的一些询问,只要判断是否f[sta]<=i就行,也就是寻求的数是否在i之前出现。(dp一下即可)

  我也不知道我在讲什么。。若是不嫌弃蒟蒻的题解的话。。边看代码边食用吧?。

【代码】

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int N=300005;
 6 const int S=1100005;
 7 int n,x,now;
 8 int f[S],a[N];
 9 int main()
10 {
11     scanf("%d",&n);
12     memset(f,0x3f,sizeof(f));
13     f[0]=0;
14     for (int i=1;i<=n;++i)
15     {
16         scanf("%d",&a[i]);
17         a[i]^=a[i-1];
18         f[a[i]]=min(f[a[i]],i);
19     }
20     for (int i=0;i<20;++i)
21         for (int j=0;j<1<<20;++j)
22             if (!(j>>i&1))    f[j]=min(f[j],f[j|1<<i]);
23     for (int i=1;i<=n;++i)
24     {
25         now=0;
26         for (int j=19;~j;--j)
27             if (!(a[i]>>j&1) && f[now|1<<j]<=i)    now|=1<<j;
28         printf("%d\n",now+now+a[i]);
29     }
30     return 0;
31 }

原文地址:https://www.cnblogs.com/Bleacher/p/8659336.html

时间: 2024-08-01 15:05:54

bzoj5092: [Lydsy1711月赛]分割序列的相关文章

bzoj 5092 [Lydsy1711月赛]分割序列——高维前缀和

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5092 套路地弄一个前缀异或和,就变成 f[ i ]=max_{j=0}^{i} { s[ j ] + (s[ i ]^s[ j ]) }.再套路地考虑按位贪心. 然后看了题解.按位贪心不是确定 f[ i ] 的这一位是0还是1,而是确定这一位是否给答案贡献 bin[ j ] ! 按位考虑,自己这一位如果是1,则 j 不管取在哪,都只有一种情况,就是向答案贡献 bin[ j ]: 自己这一位

bzoj 5093 [Lydsy1711月赛]图的价值 NTT+第二类斯特林数

[Lydsy1711月赛]图的价值 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 245  Solved: 128[Submit][Status][Discuss] Description “简单无向图”是指无重边.无自环的无向图(不一定连通). 一个带标号的图的价值定义为每个点度数的k次方的和. 给定n和k,请计算所有n个点的带标号的简单无向图的价值之和. 因为答案很大,请对998244353取模输出. Input 第一行包含两个正整数n,k(

bzoj 5092 分割序列 —— 高维前缀和

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5092 首先,处理出异或前缀和 s[i],i 位置的答案就是 s[j] + s[j]^s[i],j <= i 异或的套路是按位考虑,但是这里有加法...怎么考虑进位? 所以就不能考虑答案的这一位是什么,而应该考虑在这一位上的贡献,那么即使进位了,还是各位算各位的贡献,互相独立: 然后发现,如果 s[i] 在第 k 位上是1,那么 s[j] 的第 k 位无论是0还是1,总体的贡献都是 1<&

【bzoj5093】[Lydsy1711月赛]图的价值(NTT+第二类斯特林数)

题意: 给定\(n\)个点,一个图的价值定义为所有点的度数的\(k\)次方之和. 现在计算所有\(n\)个点的简单无向图的价值之和. 思路: 将式子列出来: \[ \sum_{i=1}^n\sum_{j=0}^{n-1}{n-1\choose j}2^{\frac{(n-1)(n-2)}{2}}j^k \] 表示分别考虑每个点的贡献,我们只需要枚举其度数即可,其余的边任意连. 然后我们将后面的\(j^k\)用第二类斯特林数展开: \[ \begin{aligned} &\sum_{i=1}^{n

【BZOJ】【3675】【APIO2014】序列分割

DP+斜率优化 首先我们根据这个分割的过程可以发现:总得分等于k+1段两两的乘积的和(乘法分配律),也就是说与分割顺序是无关的. 再对乘积进行重分组(还是乘法分配律)我们可以转化为:$ans=\sum$第 i 段×前 i-1 段的和 所以我们就可以以分割次数为阶段进行DP啦- 令f[i][j]表示将前 j 个数分成 i 段的最大得分,那么就有$$f[i][j]=max\{ f[i-1][k]+sum[k]×(sum[j]-sum[k]) \}$$我们观察到这个式子其实是很像斜率优化的……而且su

动态规划(斜率优化):BZOJ 3675 [Apio2014]序列分割

Description 小H最近迷上了一个分割序列的游戏.在这个游戏里,小H需要将一个长 度为N的非负整数序列分割成k+l个非空的子序列.为了得到k+l个子序列, 小H将重复进行七次以下的步骤: 1.小H首先选择一个长度超过1的序列(一开始小H只有一个长度为n的 序列一一也就是一开始得到的整个序列): 2.选择一个位置,并通过这个位置将这个序列分割成连续的两个非空的新 序列. 每次进行上述步骤之后,小H将会得到一定的分数.这个分数为两个新序 列中元素和的乘积.小H希望选择一种最佳的分割方案,使得

【斜率DP】BZOJ 3675:[Apio2014]序列分割

3675: [Apio2014]序列分割 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 1066  Solved: 427[Submit][Status][Discuss] Description 小H最近迷上了一个分割序列的游戏.在这个游戏里,小H需要将一个长 度为N的非负整数序列分割成k+l个非空的子序列.为了得到k+l个子序列, 小H将重复进行七次以下的步骤: 1.小H首先选择一个长度超过1的序列(一开始小H只有一个长度为n的 序列一一也就

三种快速排序以及快速排序的优化

一.  快速排序的基本思想 快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小.之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的. 二.  快速排序的三个步骤 1) 选择基准:在待排序列中,按照某种方式挑出一个元素,作为 "基准"(pivot): 2) 分割操作:以该基准在序列中的实际位置,把序列分成两个子序列.此时,在基准左边的元素都比该基准小,在基准右边的元素都比基准大: 3) 递归地对两个序列进行快速排序,直到

经典排序算法--快速排序

一.快速排序的基本思想: 快速排序使用了分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小.之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的. 二.快速排序的三个步骤 1) 选择基准:在待排序列中,按照某种方式挑出一个元素,作为 "基准"(pivot): 2) 分割操作:以该基准在序列中的实际位置,把序列分成两个子序列.如果为升序,则此时,在基准左边的元素都比该基准小,在基准右边的元素都比基准大:而基准则在排序后正确的位置上.