ベーステンプレート
より大きいまたは小さいサブセグメントSに等しい和
ll sum=0;
int l=1,r=1;
while(true){
//全速推进r指针
while(r<=n && sum<s){
sum+=a[r++];
}
//r走到头,sum无法再增大,答案无法更优
if(sum<s){
break;
}
//更新答案
ans=min(ans,r-l);
//龟速推进l指针
sum-=a[l++];
}
例
POJ3061
タイトルの上にそのテンプレート
HDU5672
問題の意味
異なる文字の数がkよりも大きい文字列が与えられると、サブストリングの必要数は同じです。
分析
- 手紙の異なる数/数も一般的に足のエミュレートに関連して。
- 先にrに同じルーチン、フルスピード、文字の数をカウント表示され、異なる文字の数、そして累積答え、リットルを進め亀の速度を更新します。
コード
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+50;
char s[N];
int T,k;
int cnt[30];
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--){
memset(cnt,0,sizeof(cnt));
scanf("%s",s+1);
scanf("%d",&k);
int n=strlen(s+1);
ll ans=0;
int num=0;
int l=1,r=1;
while(true){
while(r<=n && num<k){
cnt[s[r]-'a']++;
if(cnt[s[r]-'a']==1){
num++;
}
r++;
}
if(num<k){
break;
}
ans+=(n-(r-1)+1);
cnt[s[l]-'a']--;
if(cnt[s[l]-'a']==0){
num--;
}
l++;
if(l>r){
r=l+1;
}
}
printf("%lld\n",ans);
}
return 0;
}
HDU5056
問題の意味
文字列が与えられると、列内に現れるすべての文字の必要数は、サブストリングの数がkに等しい未満です。
分析
- 同じアイデアは足をエミュレートされていますが、文言は多少異なります。
- \(CNTは\)また、各セクションの文字の現在の数、フルスピード維持\(R&LTの\)は、文字を追加していない\(S [R&LT]を\)場合、\(CNT [S [R] - [A 「] <= K \) 、累積直接答え、そうでなければ、文字、削除\(R \)背中合わせには、事前の\(Lを\) 。
コード
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+50;
char s[N];
int T,k;
int cnt[30];
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--){
memset(cnt,0,sizeof(cnt));
scanf("%s",s+1);
scanf("%d",&k);
int n=strlen(s+1);
ll ans=0;
int l=1,r=1;
while(l<=n){
while(r<=n){
cnt[s[r]-'a']++;
if(cnt[s[r]-'a']<=k){
ans+=r-l+1;
r++;
}else{
cnt[s[r]-'a']--;
break;
}
}
cnt[s[l]-'a']--;
l++;
}
printf("%lld\n",ans);
}
return 0;
}