【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 }
null