UVa1451 数形结合

//#include<bits/stdc++.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<iostream>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
using namespace std;
#define ll long long
#define pb push_back

const int maxn=2e5+9;
char s[maxn];
int sum[maxn];
int Q[maxn];

int cmp(int x1,int x2,int x3,int x4){	//比较x1-x2 ,x3-x4的斜率
	return (sum[x2]-sum[x1])*(x4-x3)-(sum[x4]-sum[x3])*(x2-x1);
}

int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		int n,len;
		scanf("%d%d%s",&n,&len,s+1);
		sum[0]=0;
		for(int i=1;i<=n;i++)sum[i]=sum[i-1]+s[i]-'0';
		
		int ansl=0,ansr=len;//ansl不要
		int l=0,r=0;
		for(int i=len;i<=n;i++){
			while(r-l>1 && cmp(Q[r-1],i-len,Q[r-2],i-len)<0)r--;//删上凸点
			Q[r++]=i-len;
			while(r-l>1 && cmp(Q[l+1],i,Q[l],i)>=0)l++;//l+1斜率更大
			//l寻找切点
			int tt=cmp(Q[l],i,ansl,ansr);
			if(tt>0 || tt==0&&(i-Q[l]<ansr-ansl))ansr=i,ansl=Q[l];
		}
		printf("%d %d
",ansl+1,ansr);
	}
}

细节都在注释里了

相关的论文暂时不会去看,等到学计算几何的时候集中攻略吧

原文地址:https://www.cnblogs.com/Drenight/p/8611309.html