【排序】DNA Regions UVALive - 3716
分析
这题核心思想是数学变换:
方便起见,我们考虑一个左开右闭的区间 \((L, R]\),一个合法的区间满足:
\[\frac{sum_R - sum_L}{R-L}\geq p\%
\]
化简可得:
\[100sum_L -pL \geq 100sum_R -pR
\]
我们记 \(v_x=sum_x-px\),也就是我们要保证 \(v_L\geq v_R\)。
因此我们可以根据 \(v\) 值排序,题目转化为从一个长度为 \(n+1\) 的序列,序列中的元素有属性 \(x,v\) (\(x\) 代表原来的坐标)中找到左右两个点使得 \(x_r-x_l\) 最大。
这可以通过预处理出前缀最小值和后缀最大值线性时间复杂度(\(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;
}