首页 > 其他分享 >LOJ6564 最长公共子序列

LOJ6564 最长公共子序列

时间:2022-10-26 23:34:11浏览次数:82  
标签:LOJ6564 00 int 最低 差分 long 序列 最长

link:https://loj.ac/p/6564

就是求 LCS,数据范围变成 \(70000\) 了。

还是考虑朴素的 DP 状态 \(f(i,j)=\max\{f(i-1,j),f(i,j-1),[a_i=b_j]f(i-1,j-1)\}\)。

一个可能有用的性质是 \(|f(i,j)-f(i,j-1)|\le1\),如果能快速求出最后一行的差分就做完了。

这些差分都能表示成 \(01\) 串,看起来是很有前途的,把差分数组设为 \(d\)。

观察一下每次 \(i\) 加一时 \(d\) 的变化,先把所有 \(a_i=b_j\) 的 \(j\) 弄出来。

如果一个 \(j\) 大于 \(d\) 中 \(1\) 的最高位,且没有更大的 \(j'\) 了,显然能令 \(d_j=1\)。

考虑最低的 \(j\),假设其低于 \(d\) 中最低的 \(1\),那么让这个 \(1\) 移到 \(j\) 处是必然的。发现这个 \(j\) 也不可能造成其它贡献了。

实际上干的事是:有若干段 \(00\cdots01\),后缀是 \(00\cdots0\),每段的 \(1\) 尽量被 \(j\) 更新到前面(但不能到前一段),后缀 \(0\) 也把最小的 \(d_j\) 变成 \(0\)。

思考如何用位运算实现:

现在把数组 \(d\) 压成了数 \(D\),\(a_i=b_j\) 的 \(j\) 压成了 \(X\)。

现在要把每一段最低的 \(1\) 给提出来。

如 \(11\cdots100\cdots0\),要让最低的 \(1\) 和其它的区分出来,减 \(1\) 是一个很好的方法,所有 \(1\) 只有它变化了。

所有把变化了的抠出来,即异或,再与上原来的 \(1\) 即可。

具体式子是 \(D=((D|X)-(D<<1|1))\oplus(D|X)\&(D|X)\)。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int N=70005,B=63,M=N/B+1;
int n,m,k,ans;
ull f[M],b[N][M];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=0,x;i<n;i++) scanf("%d",&x),b[x][i/B]|=1llu<<i%B;
	k=(n-1)/B+1;
	for(int p;m--;){
		scanf("%d",&p);
		ull c=1;
		for(int i=0;i<k;i++){
			ull x=f[i],y=x|b[p][i];
			x+=x+c+(~y&((1llu<<B)-1));
			f[i]=x&y;c=x>>B;
		}
	}
	for(int i=0;i<k;i++) ans+=__builtin_popcountll(f[i]);
	printf("%d\n",ans);
	return 0;
}

标签:LOJ6564,00,int,最低,差分,long,序列,最长
From: https://www.cnblogs.com/shrshrshr/p/16830572.html

相关文章

  • 时序乘法器与序列乘法器
    今天学习了时序乘法器与序列乘法器,时序乘法器的思路是利用时钟做周期性乘法,具体内容见书籍《verilog应用设计实例》的290页,代码如下:moduletest_net(x_in,y_in,clk,i......
  • ctfshow反序列化 刷题随笔
    刷题随笔web254题目直接传参,没啥好说的web255题目<?phperror_reporting(0);highlight_file(__FILE__);include('flag.php');classctfShowUser{public$......
  • 最长连续序列
    题目来源​​LongestConsecutiveSequence​​问题描述给定一个未排序的整数数组,找出最长连续序列的长度。例如,给出[100,4,200,1,3,2],这个最长的连续序列是[1,......
  • 最长公共子序列问题
    最长公共子序列问题作者:Grey原文地址:博客园:最长公共子序列问题CSDN:最长公共子序列问题题目描述给定两个字符串text1和text2,返回这两个字符串的最长公共子序列的......
  • 最长非递减子序列--顺丰2020校招笔试题
    n的范围是[0,100000]DP版本(O(n^2))时间复杂度(LTE):#include<cstdio>#include<iostream>#include<algorithm>usingnamespacestd;#defineN100intmain(){intA[N],dp[N......
  • 手撕代码——最长不包含重复字符的字符串长度
    3. LongestSubstringWithoutRepeatingCharactersMedium6059348FavoriteShareGivenastring,findthelengthofthe longestsubstring withoutrepeatingcharact......
  • 最长递增子序列
    题目描述给定一个序列An=a1,a2, ...,an,找出最长的子序列使得对所有i<j,ai<aj。求出这个子序列的长度输入描述:输入的序列输出描述:最长递增子序列的长度示......
  • 求两个字符串的最长公共子字符串长度
    题目描述给定两个字符串,请编写代码,输出最长公共子串(LongestCommonSubstring),是指两个字符串中的最长的公共子串,要求子串一定是连续。输入描述:文本格式,2个非空字符串(字母......
  • 最长对称子字符串
    题目描述给定一个字符串(数字或大小写字母),找出最长的对称的子串(如有多个,输出任意一个)。例如:输入:“abbaad”输出:“abba”输入描述:字符串输出描述:字符串示例1输入复制......
  • .Net内置JSON序列化中文问题
    今天在用System.Text.Json序列化的时候遇到了中文序列化的一个问题,示例如下:JsonSerializer.Serialize(new{Name="你好"});预期结果是:{"Name":"你好"},但得到结果如下......