Live2D

Solution -「CF 1392G」Omkar and Pies

Description

  Link.

  给定两个长度为 K01S,Tn 组操作 (ai,bi),意义为交换 SaiSbi。你需要执行一段长度不小于 m 的连续操作区间,最大化 ST 相同的位数。求出最大相同位数。

  K20mn106

Solution

  一个简单的性质:ST 同时执行相同操作,答案不变。

  那么可以想到利用后缀和——记 Si 表示 S 依次执行操作 in 所得到的串,Ti 同理。根据性质,S 操作区间 [l,r] 后与 T 的相同位数等于 SlTr+1 的相同位数。

  现在问题变成,给定两个长为 n+1 的串序列 {Sn+1},{Tn+1},求:

max1i+m1rn+1{same(Si,Tj)}

  其中 same 表示两个串的相同位数。

  接下来考虑 DP。定义:

f(0,v)=minvSiif(1,v)=maxvTii

  枚举二进制 v,转移,如果有 f(0,v)+m1f(1,v),就可以用 popcount(v) 更新答案。

Code

/* Clearink */

#include <cstdio>

inline int rint ( const int base = 10 ) {
	int x = 0; char s = getchar ();
	for ( ; s < '0' || '9' < s; s = getchar () );
	for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * base + ( s ^ '0' );
	return x;
}

template<typename Tp>
inline void wint ( Tp x ) {
	if ( x < 0 ) putchar ( '-' ), x = ~ x + 1;
	if ( 9 < x ) wint ( x / 10 );
	putchar ( x % 10 ^ '0' );
}

inline void chkmin ( int& a, const int b ) { b < a ? a = b : 0; }
inline void chkmax ( int& a, const int b ) { a < b ? a = b : 0; }

const int MAXN = 1e6, MAXS = 1 << 20;
int n, m, S, T, K, a[MAXN + 5], b[MAXN + 5], p[MAXN + 5], f[2][MAXS | 5];

inline int swp ( int x ) {
	int ret = 0;
	for ( int i = 0; i < K; ++ i ) ret |= ( ( x >> i ) & 1 ) << p[i];
	return ret;
}

int main () {
	n = rint (), m = rint (), K = rint ();
	S = rint ( 2 ), T = rint ( 2 );
	for ( int i = 1; i <= n; ++ i ) a[i] = K - rint (), b[i] = K - rint ();
	for ( int s = 0; s < 1 << K; ++ s ) f[0][s] = n + 1, f[1][s] = -1;
	f[1][T] = n + 1;
	for ( int i = 0; i < K; ++ i ) p[i] = i;
	for ( int i = n; i; -- i ) {
		p[a[i]] ^= p[b[i]] ^= p[a[i]] ^= p[b[i]];
		chkmin ( f[0][swp ( S )], i ), chkmax ( f[1][swp ( T )], i );
	}
	int ans = -1, ansl = -1, ansr = -1;
	for ( int s = ( 1 << K ) - 1; ~s; -- s ) {
		for ( int i = 0; i < K; ++ i ) {
			if ( !( ( s >> i ) & 1 ) ) continue;
			chkmin ( f[0][s ^ ( 1 << i )], f[0][s] );
			chkmax ( f[1][s ^ ( 1 << i )], f[1][s] );
		}
		if ( f[1][s] - f[0][s] >= m ) {
			if ( int t = __builtin_popcount ( s ); ans < t ) {
				ans = t, ansl = f[0][s], ansr = f[1][s] - 1;
			}
		}
	}
	ans = 2 * ans + K - __builtin_popcount ( S ) - __builtin_popcount ( T );
	wint ( ans ), putchar ( '\n' );
	wint ( ansl ), putchar ( ' ' ), wint ( ansr ), putchar ( '\n' );
	return 0;
}
posted @   Rainybunny  阅读(121)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示