平衡树题
P4036 [JSOI2008] 火星人
用平衡树维护:
在位置 \(x\) 后插入一个字符。
修改位置 \(x\) 的字符。
查询区间公共前缀长度可用 hash 维护前缀,二分长度,判断 hash 值是否相等。
P3215 [HNOI2011] 括号修复 / [JSOI2011] 括号序列
lxl 大佬做法。
先看查询操作,对于任意序列 ))()()((
,其中已经匹配成功的不需要改,剩下的为 ))((
,发现序列长度为偶数时,隔一个改一个,只需改 \((a+b)/2\) 个,长度为奇数时还需额外改一个答案为 \((a+b)/2+1\)。
\(a\) 为左边右括号数量,\(b\)为右边左括号数量。
一操作:区间覆盖,一个长度为 \(len\) 的序列全部修改为右括号,那 \(a=0,b=len\)。
二操作:区间翻转,因为维护的状态只有翻转和没翻转两种状态,可以同时维护这两个状态,在进行区间翻转操作时交换值。
三操作:区间反转,同样道理也不断维护反转和没反转的状态。
可以想到要先区间反转,再区间翻转,再区间覆盖。
https://www.cnblogs.com/laijinyi/p/18449771
#include <bits/stdc++.h> #define ll long long #define int ll #define ls a[p].l #define rs a[p].r #define re register #define pb push_back #define pir pair<int,int> #define f(a,x,i) for(int i=a;i<=x;i++) #define fr(a,x,i) for(int i=a;i>=x;i--) #define lb(x) x&(-x); using namespace std; const int N=2e5+10; const int M=8e6+10; const int mod=1e9+7; mt19937 rnd(251); int n=0; int root=0; struct node{ int l,r; int siz; int rnd; int tag1;//覆盖 int tag2;//翻转 int tag3;//反转 int v1,v2;//该点类型 int vi1,vi2;//反转 int x1,z1;//未动 int x2,z2;//翻转后 int x3,z3;//反转后 int x4,z4;//反转翻转后 }a[N]; void swp(int y){ swap(a[y].x1,a[y].x2); swap(a[y].z1,a[y].z2); swap(a[y].x3,a[y].x4); swap(a[y].z3,a[y].z4); swap(a[y].l,a[y].r); a[y].tag2^=1; } void replace(int y,int k){ a[y].tag1=k;a[y].tag3=0; if(k==1){ a[y].v1=1; a[y].vi2=1; a[y].x1=a[y].siz; a[y].x2=a[y].siz; a[y].z3=a[y].siz; a[y].z4=a[y].siz; a[y].v2=0; a[y].vi1=0; a[y].z1=0; a[y].z2=0; a[y].x3=0; a[y].x4=0; } else{ a[y].v1=0; a[y].vi2=0; a[y].x1=0; a[y].x2=0; a[y].z3=0; a[y].z4=0; a[y].v2=1; a[y].vi1=1; a[y].z1=a[y].siz; a[y].z2=a[y].siz; a[y].x3=a[y].siz; a[y].x4=a[y].siz; } } void invert(int y){ swap(a[y].x1,a[y].x3); swap(a[y].z1,a[y].z3); swap(a[y].x2,a[y].x4); swap(a[y].z2,a[y].z4); swap(a[y].v1,a[y].vi1); swap(a[y].v2,a[y].vi2); a[y].tag3^=1; } void pushdown(int p){ if(a[p].tag1){ replace(ls,a[p].tag1); replace(rs,a[p].tag1); a[p].tag1=0; } if(a[p].tag2){ swp(ls); swp(rs); a[p].tag2=0; } if(a[p].tag3){ invert(ls); invert(rs); a[p].tag3=0; } } void pushup(int p){ a[p].siz=a[ls].siz+a[rs].siz+1; a[p].x1=a[ls].x1+max(0ll,a[p].v1-a[ls].z1); a[p].z1=a[p].v2+max(0ll,a[ls].z1-a[p].v1); a[p].x1=a[p].x1+max(0ll,a[rs].x1-a[p].z1); a[p].z1=a[rs].z1+max(0ll,a[p].z1-a[rs].x1); a[p].x3=a[ls].x3+max(0ll,a[p].vi1-a[ls].z3); a[p].z3=a[p].vi2+max(0ll,a[ls].z3-a[p].vi1); a[p].x3=a[p].x3+max(0ll,a[rs].x3-a[p].z3); a[p].z3=a[rs].z3+max(0ll,a[p].z3-a[rs].x3); a[p].x2=a[rs].x2+max(0ll,a[p].v1-a[rs].z2); a[p].z2=a[p].v2+max(0ll,a[rs].z2-a[p].v1); a[p].x2=a[p].x2+max(0ll,a[ls].x2-a[p].z2); a[p].z2=a[ls].z2+max(0ll,a[p].z2-a[ls].x2); a[p].x4=a[rs].x4+max(0ll,a[p].vi1-a[rs].z4); a[p].z4=a[p].vi2+max(0ll,a[rs].z4-a[p].vi1); a[p].x4=a[p].x4+max(0ll,a[ls].x4-a[p].z4); a[p].z4=a[ls].z4+max(0ll,a[p].z4-a[ls].x4); } void split(int p,int k,int &x,int &y){ if(!p){ x=y=0; return; } pushdown(p); if(a[ls].siz<k){ x=p; k-=a[ls].siz+1; split(rs,k,rs,y); } else{ y=p; split(ls,k,x,ls); } pushup(p); } int merge(int x,int y){ if(!x||!y){ return x|y; } pushdown(x); pushdown(y); if(a[x].rnd<a[y].rnd){ a[x].r=merge(a[x].r,y); pushup(x); return x; } else{ a[y].l=merge(x,a[y].l); pushup(y); return y; } } int newnode(int v){ a[++n].rnd=rnd(); a[n].siz=1; if(v==1){ a[n].v1=1; a[n].vi2=1; a[n].x1=1; a[n].x2=1; a[n].z3=1; a[n].z4=1; } else{ a[n].v2=1; a[n].vi1=1; a[n].z1=1; a[n].z2=1; a[n].x3=1; a[n].x4=1; } return n; } int F(int x){ return x / 2 + (x % 2 == 1); } signed main(){ // freopen("a.in","r",stdin); ios::sync_with_stdio(0); cin.tie(nullptr); int len,m; string s; cin>>len>>m>>s; for(int i=0;i<len;i++){ int k=2; if(s[i]==')'){ k=1; } root=merge(root,newnode(k)); } for(int i=1;i<=m;i++){ int l,r; string op; cin>>op>>l>>r; int x,y,z; split(root,l-1,x,y); split(y,r-l+1,y,z); if(op[0]=='Q'){ cout<<F(a[y].x1)+F(a[y].z1)<<"\n"; } else if(op[0]=='R'){ char c; cin>>c; int k=2; if(c==')'){ k=1; } replace(y,k); } else if(op[0]=='I'){ invert(y); } else{ swp(y); } root=merge(merge(x,y),z); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具