牛客挑战赛38 B.子串翻转

题目链接
思路:用一个大小为m双端队列的双端队列 维护一下当前窗口的串是啥。翻转就是把标记变一下。根据标记进行字符的进出。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 3e6 + 10;
#define fi first
#define se second
#define pb push_back
int n,m,q;
char a[N];
pair<char,int>b[N];
char ans[N];
int cnt;
int rev[N];
int main() {
  scanf("%d%d%d",&n,&m,&q);
  scanf("%s",a+1);
  int l=1000005,r=l-1;
  for(int i=1;i<=m;i++)b[++r]=make_pair(a[i],i);
  int sta=0,pre=1,tmp=0;
  auto del =[&](){
    if(!tmp){
      ans[++cnt]=a[b[l].se];
      l++;
    }else{
      ans[++cnt]=a[b[r].se];
      r--;
    }
    return ;
  };
  int mx=0;
  for(int i=1;i<=q;i++){
    int L,R;
    scanf("%d%d",&L,&R);
    if(L==1){
      mx=max(mx,R+m-1);
      for(int j=pre+1;j<=R;j++){
        del();
        if(!tmp)b[++r]=make_pair(a[j+m-1],j+m-1);
        else b[--l]=make_pair(a[j+m-1],j+m-1);
      }
      pre=R;
      tmp^=1;
    }else{
      if(R<=cnt)printf("%c",ans[R]);
      else if(R>mx)printf("%c",a[R]);
      else{
        if(tmp){
          printf("%c",b[r-(R-cnt)+1].fi);
        }else{
          printf("%c",b[(R-cnt)+l-1].fi);
        }
      }
    }
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40655981/article/details/105010187