【CF1263E】Editor(线段树,栈)

题意:有一个无限长度的文本编辑器,刚开始没有内容,光标在第一格,接下来有n个操作,操作可能有3种:

1.光标左移一格,如果已经在第一格则不动

2.光标右移一格

3.将当前光标所在格的字符改成输入的字符

每次操作后问当前所有内容对于括号序列是否合法,若非法输出-1,否则输出括号的最大层数

n<=1e6

思路:最大层数即将左括号看做-1,右括号看做1之后的最大前缀和

做法一:线段树单点修改

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef long double ld;
  7 typedef pair<int,int> PII;
  8 typedef pair<ll,ll> Pll;
  9 typedef vector<int> VI;
 10 typedef vector<PII> VII;
 11 typedef pair<ll,ll>P;
 12 #define N  2000000+10
 13 #define M  200000+10
 14 #define INF 1e9
 15 #define fi first
 16 #define se second
 17 #define MP make_pair
 18 #define pb push_back
 19 #define pi acos(-1)
 20 #define mem(a,b) memset(a,b,sizeof(a))
 21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 23 #define lowbit(x) x&(-x)
 24 #define Rand (rand()*(1<<16)+rand())
 25 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 26 #define ls p<<1
 27 #define rs p<<1|1
 28 #define fors(i) for(auto i:e[x]) if(i!=p)
 29 
 30 const int MOD=998244353,inv2=(MOD+1)/2;
 31       //int p=1e4+7;
 32       //double eps=1e-6;
 33       int dx[4]={-1,1,0,0};
 34       int dy[4]={0,0,-1,1};
 35 
 36 struct node
 37 {
 38     int s,mx,mn;
 39 }t[N<<2];
 40 
 41 char s[N];
 42 
 43 int read()
 44 {
 45    int v=0,f=1;
 46    char c=getchar();
 47    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 48    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 49    return v*f;
 50 }
 51 
 52 ll readll()
 53 {
 54    ll v=0,f=1;
 55    char c=getchar();
 56    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 57    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 58    return v*f;
 59 }
 60 
 61 void build(int l,int r,int p)
 62 {
 63     t[p].s=t[p].mx=t[p].mn=0;
 64     if(l==r) return;
 65     int mid=(l+r)>>1;
 66     build(l,mid,ls);
 67     build(mid+1,r,rs);
 68 }
 69 
 70 void pushup(int p)
 71 {
 72     t[p].s=t[ls].s+t[rs].s;
 73     t[p].mx=max(t[ls].mx,t[ls].s+t[rs].mx);
 74     t[p].mn=min(t[ls].mn,t[ls].s+t[rs].mn);
 75 }
 76 
 77 void update(int l,int r,int x,int d,int p)
 78 {
 79     if(l==r)
 80     {
 81         t[p].s=d;
 82         t[p].mx=d;
 83         t[p].mn=d;
 84         return;
 85     }
 86     int mid=(l+r)>>1;
 87     if(x<=mid) update(l,mid,x,d,ls);
 88      else update(mid+1,r,x,d,rs);
 89     pushup(p);
 90 }
 91 
 92 int main()
 93 {
 94     //freopen("1.in","r",stdin);
 95     //freopen("1.out","w",stdout);
 96     int n=read();
 97     build(1,1e6+10,1);
 98     int now=1;
 99     rep(i,1,n)
100     {
101         char c=getchar();
102         if(c=='L')
103         {
104             if(now>1) now--;
105             if(t[1].s!=0||t[1].mn<0) printf("-1 ");
106              else printf("%d ",t[1].mx);
107             //printf("now=%d t[1].s=%d t[1].mx=%d\n",now,t[1].s,t[1].mx);
108             continue;
109         }
110         if(c=='R')
111         {
112             now++;
113             if(t[1].s!=0||t[1].mn<0) printf("-1 ");
114              else printf("%d ",t[1].mx);
115             //printf("now=%d t[1].s=%d t[1].mx=%d\n",now,t[1].s,t[1].mx);
116             continue;
117         }
118         int d=0;
119         s[now]=c;
120         if(c=='(') d=1;
121         if(c==')') d=-1;
122         update(1,1e6+10,now,d,1);
123         if(t[1].s!=0||t[1].mn<0) printf("-1 ");
124          else printf("%d ",t[1].mx);
125         //printf("now=%d t[1].s=%d t[1].mx=%d\n",now,t[1].s,t[1].mx);
126     }
127     return 0;
128 }

思路二:用栈维护光标左边的内容,右边的内容和当前左部分前缀和对于真正值的偏移量,维护的信息和线段树差不多

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef long double ld;
  7 typedef pair<int,int> PII;
  8 typedef pair<ll,ll> Pll;
  9 typedef vector<int> VI;
 10 typedef vector<PII> VII;
 11 typedef pair<ll,ll>P;
 12 #define N  2000000+10
 13 #define M  200000+10
 14 #define INF 1e9
 15 #define fi first
 16 #define se second
 17 #define MP make_pair
 18 #define pb push_back
 19 #define pi acos(-1)
 20 #define mem(a,b) memset(a,b,sizeof(a))
 21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 23 #define lowbit(x) x&(-x)
 24 #define Rand (rand()*(1<<16)+rand())
 25 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 26 #define ls p<<1
 27 #define rs p<<1|1
 28 #define fors(i) for(auto i:e[x]) if(i!=p)
 29 
 30 const int MOD=998244353,inv2=(MOD+1)/2;
 31       //int p=1e4+7;
 32       //double eps=1e-6;
 33       int dx[4]={-1,1,0,0};
 34       int dy[4]={0,0,-1,1};
 35 
 36 int a[N],s[N];
 37 
 38 struct Set
 39 {
 40     int mn,mx;
 41     int cnt[4000001];
 42     Set():mn(0),mx(0),cnt{}{cnt[2000000]=10000000;}
 43     void Insert(int x)
 44     {
 45         cnt[x+2000000]++;
 46         mn=min(mn,x);
 47         mx=max(mx,x);
 48     }
 49     void Erase(int x)
 50     {
 51         cnt[x+2000000]--;
 52         while(cnt[mn+2000000]==0) mn++;
 53         while(cnt[mx+2000000]==0) mx--;
 54     }
 55 };
 56 
 57 int read()
 58 {
 59    int v=0,f=1;
 60    char c=getchar();
 61    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 62    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 63    return v*f;
 64 }
 65 
 66 ll readll()
 67 {
 68    ll v=0,f=1;
 69    char c=getchar();
 70    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 71    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 72    return v*f;
 73 }
 74 
 75 int main()
 76 {
 77     //freopen("1.in","r",stdin);
 78     //freopen("1.out","w",stdout);
 79     int n=read();
 80     //printf("n=%d\n",n);
 81     int offset=0,p=0,tot=0;
 82     Set l,r;
 83     rep(i,1,n)
 84     {
 85         char c=getchar();
 86         if(c=='L')
 87         {
 88             if(p>0)
 89             {
 90                 l.Erase(s[p]);
 91                 p--;
 92                 r.Insert(-offset);
 93                 offset+=a[p];
 94             }
 95         }
 96          else if(c=='R')
 97          {
 98              offset-=a[p];
 99              r.Erase(-offset);
100              p++;
101              s[p]=s[p-1]+a[p-1];
102              l.Insert(s[p]);
103          }
104           else
105           {
106               int v=0;
107               if(c=='(') v=1;
108               if(c==')') v=-1;
109               offset+=v-a[p];
110               tot+=v-a[p];
111               a[p]=v;
112           }
113         if(tot!=0||min(l.mn,offset+s[p]+r.mn)<0) printf("-1\n");
114          else printf("%d\n",max(l.mx,offset+s[p]+r.mx));
115     }
116     return 0;
117 }

 

posted on 2019-12-02 16:22  myx12345  阅读(313)  评论(0编辑  收藏  举报

导航