【排序】DNA Regions UVALive - 3716

分析

这题核心思想是数学变换:
方便起见,我们考虑一个左开右闭的区间 (L,R],一个合法的区间满足:

sumRsumLRLp%

化简可得:

100sumLpL100sumRpR

我们记 vx=sumxpx,也就是我们要保证 vLvR

因此我们可以根据 v 值排序,题目转化为从一个长度为 n+1 的序列,序列中的元素有属性 x,vx 代表原来的坐标)中找到左右两个点使得 xrxl 最大。

这可以通过预处理出前缀最小值后缀最大值线性时间复杂度(O(n))求解。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb push_back
#define eb emplace_back
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)

#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

const int N=15e4+5;

int n, p;
char s[N], t[N];

struct Node{
	int x, v;
	bool operator < (const Node &o)const{
		return v==o.v? x<o.x: v>o.v; 
	}
}e[N];

int pre[N], suf[N];

int main(){
	while(cin>>n>>p, n || p){
		cin>>s+1>>t+1;
		
		e[0]={0, 0}; int sum=0;
		rep(i,1,n){
			if(s[i]!=t[i]) sum++;
			e[i]={i, 100*sum-p*i};
		}
		
		sort(e, e+n+1);
		
		pre[0]=e[0].x, suf[n]=e[n].x;
		rep(i,1,n) pre[i]=min(pre[i-1], e[i].x);
		dwn(i,n-1,0) suf[i]=max(suf[i+1], e[i].x);
		
		int res=-1;
		rep(i,0,n-1) res=max(res, suf[i+1]-pre[i]);
		if(res==-1) puts("No solution.");
		else cout<<res<<endl;
	}
    return 0;
}
posted @   HinanawiTenshi  阅读(44)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示