ZSTU2019校赛 Problem D Lis(线性基dp)
我的做题思路参考的是这位大佬(代码就把他的抄了一遍)
https://blog.csdn.net/kzn2683331518/article/details/88768657
题面:
令LIS(S)为序列S的最长递增子序列的长度
给你n个非负整数,a[0],a[1],...,a[n-1],你可以对这个数组进行零次或多次操作,每次操作选择一个i(0<=i<=n-2),将a[i+1]变成(a[i+1] xor a[i])
你的任务是使得LIS(a)越大越好,输出LIS(a)的最大值
解题思路:
一步步来
1. 首先知道a^b^b = a 这个性质,并且一个数可以无限次异或前一位。
那么举个例子
a1 a2 a3 a4,请问a4可以得到哪几种异或的结果?
①:a2=a2^a1 --> a3=a3^(a2^a1) --> a4=a4^(a3^a2^a1),这是第一种
②:a3=a3^a2 --> a4=a4^(a3^a2),这是第二种
③:a4 = a4^a3,这是第三种
④ :在①的基础上a2 =(a2^a1)^a1=a2
a3 = (a3^a2^a1)^a2=a3^a1
a4 = (a4^a3^a2^a1)^(a3^a1) = a4^a2,这是第四种
⑤:对前面三项经过多次操作后,还可以得到a4^a1, a4^a1^a2, a4^a1^a3, a4^a2^a3...
于是归纳出结论:对于a[i],可以xjb乱异或前面的a[j] (j<i)
2. 构造线性基数组
还是举个例子吧:
给你五个数:
5 7 8 9 12
转化为二进制:
101 111 1000 1001 1100
亲,跟着我这么做:
首先构造一个lb[i][j]二维数组,表示是a[i]第j位上的线性基
现在我们假设求a[6]的线性基:
①先分析一下:
我们知道,暴力求出a[6]有多少种异或的方法并得到最小值需要2的五次方次(也就是2的(i-1)次方)计算
而利用线性基求固定63次运算(n很大的时候就省时间了)
63怎么得来的(long long型正数最大二进制下63位)
②开始构造a[6]的线性基,构造完再讲一下原理:
先扔进来101,从高到低遍历,第三位是1,判断lb[6][3]是否被赋值过(显然没有,还是初始化状态)
于是lb[6][3]=101(5),oj8k,直接return。
再扔进来111,再遍历,第三位是1,但lb[6][3]被赋值过,那怎么办?把111^lb[6][3],变成了010,
再判断第二位是1,lb[6][2]没有被赋值,于是lb[6][2]=010(2),oj8k.
然后打字好累长话短说,lb[6][4]=8
lb[6][1] = 1
最后的1100变成0,最后没有进入lb[6]的线性基
最后,看构造出来的lb[6]结果:
0101
0010
1000
0001
因为前五个数没有超过15的,所以只要四位就够了,这样四个每个都有一个1在各自位子上的数一定可以表示出这四个数异或出来的所有结果,而a[6]异或最大值只要将他的线性基从高到低遍历,如果当前线性基使得结果增大,那么就异或一下。
(这里具体我就说不清了,根据a^b^b=a这个性质应该可以证明)
3.构造dp数组:
前面求得了线性基,最终目的是修改a[i]的值,使其比a[i-1]大的同时尽可能小。
dp[i][j]表示前i位长度为j的lis最小后缀(注意LIS不必是连续的一串,中间可以断一下)
dp[i][j] = min (dp[i-1][j],计算得来的dp[i][j]);
4.关于代码里求比上一项大的最小值的那一坨代码(getminmax)的解释
看懂了代码其他部分再来看吧
先预设x为最大值,
if(x<g)滚,没有,最大的都不是
else {
x异或当前位,判断是否比g大,
大就判断和之前x谁大
小就对后面的基搞来搞去,搞出后面的基可以异或出的最大的数
如果比g大,那么此时最小的x就变成tmp
要问为什么?(因为我来了) x = same 1 xxxx >g
这个 tmp = same 0 yyyy > g
}
代码:(这个1要longlong 是真的挺坑的,我打赌以后自己还会错)
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;const int N = 105;ll lb[N][65],dp[N][N],a[N];void get_lb(int i,ll x)
{for (int j = 62;j>=0;j--){if ((x>>j)&1){//if (((ll)1<<j)&x){//或者这样,但是记得longlongif (!lb[i][j+1]){lb[i][j+1] = x;return ;}else x = x^lb[i][j+1];}}
}ll getmin(int i,ll x)
{ll ans = x;for (int j=63;j>=1 && ans;j--){ans = min(ans,ans^lb[i][j]);}return ans;
}ll getminmax(int i,ll x)
{ll ans = a[i];///不要写成 = x -_-||for (int j=63;j>=1;j--) ans = max(ans,ans^lb[i][j]);if (ans<=x) return INF;for (int j=63;j>=1;j--){ll temp = ans^lb[i][j];if (temp>ans) continue;if (temp>x) ans = temp;else {for (int k=j-1;k>=1;k--)temp = max(temp,temp^lb[i][k]);if (temp>x) ans = temp; }}return ans;
}int main()
{int n;while (~scanf("%d",&n)){memset(lb,0,sizeof lb);memset(dp,INF,sizeof dp);for (int i=1;i<=n;i++) scanf("%lld",a+i);for (int i=2;i<=n;i++){memcpy(lb[i],lb[i-1],sizeof lb[i-1]);get_lb(i,a[i-1]);}dp[1][1] = a[1];for (int i=2;i<=n;i++) dp[i][1] = min(getmin(i,a[i]),dp[i-1][1]);for (int i = 2;i<=n;i++)for (int j=2;j<=i;j++)if (dp[i-1][j-1]==INF) break;else dp[i][j] = min(dp[i-1][j],getminmax(i,dp[i-1][j-1]));
/*for (int i = 1;i<=n;i++){for (int j=1;j<=i;j++){if (dp[i][j]==INF) printf("dp[%d][%d]=INF ",i,j);else printf("dp[%d][%d]=%lld ",i,j,dp[i][j]);}printf("\n");}
*/for (int i=n;i>=1;i--){if (dp[n][i]!=INF){printf("%d\n",i);break;}}}return 0;
}
ZSTU2019校赛 Problem D Lis(线性基dp)相关推荐
- 2017年ZJUT校赛-Problem C: BugZhu抽抽抽!!——解析几何
Problem C: BugZhu抽抽抽!!--解析几何 Description 当前正火的一款手游阴阳师又出新式神了,BugZhu十分想要获得新出的式神,所以他决定花光所有的积蓄来抽抽抽!BugZh ...
- 2014湖南农业大学ACM校赛
湖南农业大学 2014年 ACM 校赛Problem 2014 /2/23 星期日 12:30-17:30 A.搜素 1794.查找指定的字符串 B.链表 1795 ...
- 2019牛客多校第四场 B xor (线性基求交)
xor 思路 题目是要求[l,r][l, r][l,r]的所有集合是否都可以得到xxx,那么显然我们可以对这[l,r][l, r][l,r]个线性基求交,然后再特判能否xxx能否插入,如果能插入,显然 ...
- 2017 ICPC西安区域赛 A - XOR ,线段树合并线性基
题目链接:A - XOR 题意;给个数组,每次询问一个区间你可以挑任意个数的数字异或和 然后在或上k的最大值 题解:线性基不知道的先看这个,一个线性基可以log的求最大值把对应去区间的线性基求出来然后 ...
- 【2019牛客暑期多校训练营(第一场) - H】XOR(线性基,期望的线性性)
题干: 链接:https://ac.nowcoder.com/acm/contest/881/H 来源:牛客网 Bobo has a set A of n integers a1,a2,-,ana1, ...
- 2017 ICPC西安区域赛 A - XOR (线段树并线性基)
链接:https://nanti.jisuanke.com/t/A1607 题面: Consider an array AA with n elements . Each of its element ...
- 大学生程序设计创新实践基地2022年冬季校赛(NPU ACM Winter Contest)
大学生程序设计创新实践基地2022年冬季校赛(NPU ACM Winter Contest) 总述 总体考察对于板子的熟练变换,以及考察离谱地使用python和对getchar()以及EOF的基础掌握 ...
- 好久没撸c,第一场回状态的题(埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛
题目链接: 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 A:Wasserstein Distance ## 题意:有2大堆柱状图的土(总体积相同,问从第一堆土移动到第二堆消耗最少的 ...
- [置顶]2010年东北大学ACM程序设计竞赛冬季校赛题解
8题只做出4题比较easy的题,而且做得挺麻烦,看来还要多练练. AC的题如下 NEUOJ 1112 I Love Apple Description So many people love app ...
最新文章
- 成功网管员必备“硬件”素质
- 自定义控件:滑动开关
- log4net 使用手记
- java 构建者模式_Java不可变类–构建器模式
- 1075. PAT Judge (25)
- Python笔记3:使用命令行运行Python文件
- OpenGL ES 送显 YUV NV12
- MobaXterm使用技巧
- 汽车电子-AUTOSAR基础简介
- 2017 Top 10 Web 应用安全威胁,你的企业正在经历哪些?
- 注册邮箱账号十大品牌分析
- python气象卫星云图解析_02_中央气象台
- 从零开始学习HTML
- excel学习-填充空白单元格
- 基于Vue源码中e2e测试实践
- 【pwn】WMCTF2020 cfgo-CheckIn
- TextTranslatorOpenSource-文本翻译器开源版
- Centos 系统优化
- 笔记本计算机忘记密码,Windows笔记本电脑忘记开机登录密码忘记怎么办 最新win7/8/10开机密码重置教程...
- EDI 855 采购订单确认
热门文章
- 商品sku规格选择效果,没有商品的不能选中,选择顺序不影响展示结果
- 1.amdahl定律(加速比)
- python 几何教学_GEE学习笔记 八十三:【GEE之Python版教程十三】几何图形
- 川土微电子产品在PLC/伺服领域的应用
- vbs在excel中打开html文件,从命令行使用VBScript从Excel外部运行Excel宏
- 零基础可以学板绘吗?怎么自学板绘?
- android 安装多个app下载,多点下载2021安卓最新版_手机app官方版免费安装下载_豌豆荚...
- 中文版Geneve02
- matlab计算下列极限,MATLAB微积分计算极限,又快又好
- html5中float的用法,float的用法总结大全