Editorial for Dãy ngoặc đúng
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này
Code mẫu của ladpro98
program NKBRACKE; uses math; const maxn=100005; oo=trunc(1e9); fi=''; num:array['('..')'] of longint = (1,-1); var n,m,res,t,p,pos,l,r,ok,sl,sr:longint; s:ansistring; c:char; bit,a,sum:array[0..maxn] of longint; it,lazy:array[1..4*maxn] of longint; inp:text; procedure buildIT(k,l,r,i,v:longint); var m:longint; begin if (r<i) or (i<l) then exit; if l=r then begin it[k]:=v; exit; end; m:=(l+r) shr 1; buildIT(k shl 1,l,m,i,v); buildIT(k shl 1 or 1, m+1,r,i,v); it[k]:=min(it[k shl 1],it[k shl 1 or 1]); end; procedure updateBIT(i,v:longint); begin while i<=n do begin inc(bit[i],v); i:=i+i and (-i); end; end; function getBIT(i:longint):longint; var sum:longint; begin sum:=0; while i>0 do begin inc(sum,bit[i]); i:=i-i and (-i); end; exit(sum); end; procedure updateIT(k,l,r,i,j,v:longint); var m:longint; begin if lazy[k]<>0 then begin if l<>r then begin inc(lazy[k shl 1],lazy[k]); inc(lazy[k shl 1 or 1],lazy[k]); end; inc(it[k],lazy[k]); lazy[k]:=0; end; if (l>r) or (r<i) or (j<l) then exit; if (i<=l) and (r<=j) then begin inc(it[k],v); if l<>r then begin inc(lazy[k shl 1],v); inc(lazy[k shl 1 or 1],v); end; exit; end; m:=(l+r) shr 1; updateIT(k shl 1,l,m,i,j,v); updateIT(k shl 1 or 1, m+1,r,i,j,v); it[k]:=min(it[k shl 1],it[k shl 1 or 1]); end; procedure getIT(k,l,r,i,j:longint); var m:longint; begin if (l>r) or (r<i) or (j<l) then exit; if lazy[k]<>0 then begin if l<>r then begin inc(lazy[k shl 1],lazy[k]); inc(lazy[k shl 1 or 1],lazy[k]); end; inc(it[k],lazy[k]); lazy[k]:=0; end; if (i<=l) and (r<=j) then begin res:=min(res,it[k]); exit; end; m:=(l+r) shr 1; getIT(k shl 1,l,m,i,j); getIT(k shl 1 or 1, m+1,r,i,j); end; procedure Enter; var i:longint; begin assign(inp,fi);reset(inp); readln(inp,n,m); readln(inp,s); for i:=1 to n do a[i]:=num[s[i]]; for i:=1 to n do sum[i]:=sum[i-1]+a[i]; for i:=1 to n do buildIT(1,1,n,i,sum[i]); for i:=1 to n do updateBIT(i,a[i]); end; begin Enter; for t:=1 to m do begin read(inp,p); if p=0 then begin readln(inp,pos,c,c); if a[pos] = num[c] then continue; a[pos]:=num[c]; updateBIT(pos,num[c] shl 1); updateIT(1,1,n,pos,n,num[c] shl 1); end else begin readln(inp,l,r); if not odd(r-l) then begin write(0); continue; end; ok:=0; sl:=getBIT(l-1); sr:=getBIT(r); if sl=sr then begin res:=oo; getIT(1,1,n,l,r); if res>=sl then ok:=1; end; write(ok); end; end; end.
Code mẫu của RR
#include <sstream> #include <iomanip> #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #include <vector> #include <set> #include <map> #include <stack> #include <queue> #include <string> #include <deque> #include <complex> #define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; i++) #define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; i--) #define REP(i,a) for(int i=0,_a=(a); i<_a; i++) #define FORN(i,a,b) for(int i=(a),_b=(b);i<_b;i++) #define DOWN(i,a,b) for(int i=a,_b=(b);i>=_b;i--) #define SET(a,v) memset(a,v,sizeof(a)) #define sqr(x) ((x)*(x)) #define ll long long #define F first #define S second #define PB push_back #define MP make_pair #define DEBUG(x) cout << #x << " = "; cout << x << endl; #define PR(a,n) cout << #a << " = "; FOR(_,1,n) cout << a[_] << ' '; cout << endl; #define PR0(a,n) cout << #a << " = "; REP(_,n) cout << a[_] << ' '; cout << endl; using namespace std; //Buffer reading int INP,AM,REACHEOF; #define BUFSIZE (1<<12) char BUF[BUFSIZE+1], *inp=BUF; #define GETCHAR(INP) { \ if(!*inp) { \ if (REACHEOF) return 0;\ memset(BUF,0,sizeof BUF);\ int inpzzz = fread(BUF,1,BUFSIZE,stdin);\ if (inpzzz != BUFSIZE) REACHEOF = true;\ inp=BUF; \ } \ INP=*inp++; \ } #define DIG(a) (((a)>='0')&&((a)<='9')) #define GN(j) { \ AM=0;\ GETCHAR(INP); while(!DIG(INP) && INP!='-') GETCHAR(INP);\ if (INP=='-') {AM=1;GETCHAR(INP);} \ j=INP-'0'; GETCHAR(INP); \ while(DIG(INP)){j=10*j+(INP-'0');GETCHAR(INP);} \ if (AM) j=-j;\ } //End of buffer reading const long double PI = acos((long double) -1.0); const int MN = 800111; int n, q; char a[MN]; int op[MN], cl[MN], bad[MN]; #define CT(x) ((x)<<1) #define CP(x) (CT(x) + 1) int match_l; inline void cal(int i) { op[i] = op[CT(i)] + op[CP(i)]; cl[i] = cl[CT(i)] + cl[CP(i)]; match_l = min(op[CT(i)], cl[CT(i)] - bad[CT(i)]); bad[i] = bad[CT(i)] + max(0, bad[CP(i)] - (op[CT(i)] - match_l)); } inline void leaf(int i, char c) { if (c == '(') { op[i] = 1; cl[i] = bad[i] = 0; } else { op[i] = 0; cl[i] = bad[i] = 1; } } void init(int i, int l, int r) { if (l == r) { leaf(i, a[l]); return ; } int mid = (l + r) >> 1; init(CT(i), l, mid); init(CP(i), mid+1, r); cal(i); } void update(int i, int l, int r, int u, char c) { if (u < l || r < u) return ; if (l == r) { leaf(i, c); return ; } int mid = (l + r) >> 1; update(CT(i), l, mid, u, c); update(CP(i), mid+1, r, u, c); cal(i); } int can; bool wrong; void visit(int i, int l, int r, int u, int v) { if (v < l || r < u) return ; if (u <= l && r <= v) { if (bad[i] > can) wrong = true; can += op[i] - cl[i]; return ; } int mid = (l + r) >> 1; visit(CT(i), l, mid, u, v); visit(CP(i), mid+1, r, u, v); } void solve(int u, int v) { can = 0; wrong = false; visit(1, 1, n, u, v); if (!can && !wrong) putchar('1'); else putchar('0'); } int main() { scanf("%d%d\n", &n, &q); scanf("%s\n", &a[1]); init(1,1,n); int req, u, v; char c; while (q--) { scanf("%d", &req); if (req == 0) { scanf("%d %c", &u, &c); update(1,1,n,u,c); } else { scanf("%d%d", &u, &v); solve(u, v); } } puts(""); return 0; }
Code mẫu của skyvn97
#include<cstdio> #include<vector> #define MAX 100100 #define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i=i+1) #define REP(i,n) for (int i=0,_n=(n);i<_n;i=i+1) using namespace std; class SegmentTree { private: static const int INF=(int)1e9+7; vector<int> tree,lazy; int n; void pushdown(int i) { if (lazy[i]==0) return; FOR(j,2*i,2*i+1) { tree[j]+=lazy[i]; lazy[j]+=lazy[i]; } lazy[i]=0; } int getMin(int i,int l,int r,int u,int v,int add) const { if (l>v || r<u || l>r || v<u) return (INF); if (u<=l && r<=v) return (tree[i]+add); int m=(l+r)>>1; int L=getMin(2*i,l,m,u,v,add+lazy[i]); int R=getMin(2*i+1,m+1,r,u,v,add+lazy[i]); return (min(L,R)); } void update(int i,int l,int r,int u,int v,int c) { if (l>v || r<u || l>r || v<u) return; if (u<=l && r<=v) { tree[i]+=c; lazy[i]+=c; return; } pushdown(i); int m=(l+r)>>1; update(2*i,l,m,u,v,c); update(2*i+1,m+1,r,u,v,c); tree[i]=min(tree[2*i],tree[2*i+1]); } public: SegmentTree() { n=0; } SegmentTree(int n) { this->n=n; tree.assign(4*n+7,0); lazy.assign(4*n+7,0); } void update(int l,int r,int c) { update(1,1,n,l,r,c); } int getMin(int l,int r) const { return (getMin(1,1,n,l,r,0)); } }; class FenwickTree { private: int n; vector<int> v; public: FenwickTree() { n=0; } FenwickTree(int n) { this->n=n; v.assign(n+7,0); } void update(int x,int d) { if (x<1) return; for (;x<=n;x+=x&-x) v[x]+=d; } int getSum(int x) const { int res=0; if (x>n) return (0); for (;x>=1;x&=x-1) res+=v[x]; return (res); } }; char s[MAX]; int a[MAX]; int n,q; SegmentTree myit; FenwickTree bit; void init(void) { scanf("%d%d",&n,&q); scanf("%s",s+1); FOR(i,1,n) a[i]=s[i]=='('?1:-1; myit=SegmentTree(n); bit=FenwickTree(n); FOR(i,1,n) myit.update(i,n,a[i]); FOR(i,1,n) bit.update(i,a[i]); } void update(int x,int v) { if (a[x]==v) return; myit.update(x,n,v-a[x]); bit.update(x,v-a[x]); a[x]=v; } bool ok(int l,int r) { if ((r-l+1)%2!=0) return (false); int prevSum=l==1?0:bit.getSum(l-1); if (myit.getMin(l,r)-prevSum<0) return (false); return (bit.getSum(r)==prevSum); } void process(void) { REP(zz,q) { int t,l,r; char s[2]; scanf("%d%d",&t,&l); if (t==0) { scanf("%s",s); update(l,s[0]=='('?1:-1); } else { scanf("%d",&r); printf("%d",ok(l,r)?1:0); } } } int main(void) { init(); process(); return 0; }
Comments
.