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\n",ansl+1,ansr); } }
细节都在注释里了
相关的论文暂时不会去看,等到学计算几何的时候集中攻略吧