LOADING

加载过慢请开启缓存,浏览器默认开启

daily 3

2023/5/10 daily

今天三道双指针

CF 1324D

简单双指针,转化为$c[i]=a[i]-b[i]$即可

void solve(){
  int n;cin>>n;
  vector<int>a(n+1);
  for(int i=1;i<=n;++i){
    cin>>a[i];
  }
  for(int i=1;i<=n;++i){
    int x;cin>>x;
    a[i]-=x;
  }
  sort(a.begin()+1,a.end());
  ll ans=0;
  for(int l=1,r=n;l<=n;++l){
    while(r>1&&a[l]+a[r]>0)--r;
    ans+=n-max(l,r);
  }
  cout<<ans<<'\n';
  return;
}

CF 1680C

我们需要尽可能地让删除的1和剩下的0相等,否则不管怎么样都会增大cost,那就双指针去搜就可以了

void solve(){
  string s;
  cin>>s;
  int n=s.size();
  int cnt_1=0;
  for(int i=0;i<s.size();++i){
    if(s[i]=='1')++cnt_1;
  }
  int ans=INT_MAX;
  int cnt_0=0;
  for(int l=0,r=-1;l<n;++l){
    while(r<n&&cnt_0<cnt_1){
        ++r;
        if(s[r]=='1'){
            cnt_1--;
        }else{
            cnt_0++;
        }
        ans=min(ans,max(cnt_0,cnt_1));
    }
    if(s[l]=='0'){
        --cnt_0;
    }else{
        ++cnt_1;
    }
    ans=min(ans,max(cnt_0,cnt_1));
  }
  cout<<ans<<'\n';
  return;
}

CF 386C
三指针的题
每次搜索对应unique为i的长度的最大和最小的r,然后更新答案

#define int ll
void solve(){
  string s;
  cin>>s;
  int n=s.size();
  s='0'+s;
  vector<ll>ans;
  auto calc=[&](int lim){
    int l=1,r1=0,r2=1,res=0;
    int now_cnt=0;
    vector<int>cnt(26);
    for(;l<=n;++l){
        while(r1<n&&now_cnt<lim){
            if(++cnt[s[++r1]-'a']==1){
                ++now_cnt;
            }
        }
        if(now_cnt<lim)break;
        r2=max(r1,r2);
        while(r2<=n&&cnt[s[r2]-'a'])++r2;
        res+=(r2-r1);
        if(--cnt[s[l]-'a']==0)--now_cnt;
    }
    if(res>0)ans.push_back(res);
  };
  for(int i=1;i<=26;++i){
    calc(i);
  }
  cout<<ans.size()<<'\n';
  for(int i=0;i<ans.size();++i){
    cout<<ans[i]<<'\n';
  }
  return;
}