1. 程式人生 > >cogs1279 括號修復

cogs1279 括號修復

bool oid str spa play can urn 應該 b-

鏈接

時間限制:4 s 內存限制:128 MB

【題目描述】

技術分享圖片

註意:以評測系統提供的輸入輸出文件名為準!

這個問題乍一看很棘手,因為他詢問的東西很奇怪,所以我們考慮如果只有詢問操作,我們應該怎麽做,我們模擬一個棧來模擬括號匹配的過程,可以發現最終棧中剩下的元素一定是形如)))(((的,這時我們有一個結論 變成合法的最少修改次數為(p/2)+(q/2),註意該式子是要上取整,並且只對於p+q是偶數,奇數並不能實現完全匹配,p和q分別代表無法匹配的)和(的個數,那麽問題就轉換為了求出序列中無法匹配的)和(的個數,還是很難搞。

我們不妨對原序列做一個轉換,我們將所有的)視為-1,將所有的(視為1,那麽,p事實上就是這段區間的最小前綴的相反數,而q就是這段區間的最大後綴,因為兩者之和是等於區間和的,所以我們只需要維護其中一個即可。假設我們選擇維護最大後綴,因為有區間翻轉操作,所以我們需要額外維護一個區間最大前綴。

對於區間*-1的情況,我們考慮如何更新最大前綴和最大後綴,最大前綴*-1之後變成了最小前綴,而最小前綴+最大後綴=區間和,所以我們可以以這種方式求出新的最大後綴。

技術分享圖片
  1 #include<cstdio>
  2 #define ls ch[x][0]
  3 #define rs ch[x][1]
  4 #define mid ((l+r)>>1)
  5 #define max(a,b) a>b?a:b
  6 using namespace std;
  7 const int inf=1e5+5;
  8 int n,m;
  9
char s[inf]; 10 int rt; 11 int ch[inf][2],fa[inf],siz[inf]; 12 int v[inf],rev[inf],reset[inf],mul[inf],sum[inf],lmax[inf],rmax[inf]; 13 bool get(int x){ 14 return ch[fa[x]][1]==x; 15 } 16 void swap(int &x,int &y){ 17 int tem=x; 18 x=y; 19 y=tem; 20 } 21
void update(int x){ 22 sum[x]=sum[ls]+sum[rs]+v[x]; 23 siz[x]=siz[ls]+siz[rs]+1; 24 lmax[x]=max(lmax[ls],sum[ls]+lmax[rs]+v[x]); 25 rmax[x]=max(rmax[rs],sum[rs]+rmax[ls]+v[x]); 26 } 27 void tagdown(int x){ 28 if(reset[x]){ 29 v[x]=reset[x]; 30 sum[ls]=reset[x]*siz[ls]; 31 sum[rs]=reset[x]*siz[rs]; 32 if(reset[x]>0){ 33 lmax[ls]=rmax[ls]=siz[ls]; 34 lmax[rs]=rmax[rs]=siz[rs]; 35 } 36 else { 37 lmax[ls]=rmax[ls]=0; 38 lmax[rs]=rmax[rs]=0; 39 } 40 reset[ls]=reset[rs]=reset[x]; 41 rev[x]=0; 42 mul[x]=1; 43 reset[x]=0; 44 return ; 45 } 46 if(rev[x]){ 47 swap(ch[ls][0],ch[ls][1]); 48 swap(ch[rs][0],ch[rs][1]); 49 swap(lmax[ls],rmax[ls]); 50 swap(lmax[rs],rmax[rs]); 51 rev[ls]^=1;rev[rs]^=1; 52 rev[x]=0; 53 } 54 if(mul[x]!=1){ 55 v[x]*=-1; 56 sum[ls]*=-1; 57 sum[rs]*=-1; 58 int tem=lmax[ls]; 59 lmax[ls]=sum[ls]+rmax[ls]; 60 rmax[ls]=sum[ls]+tem; 61 tem=lmax[rs]; 62 lmax[rs]=sum[rs]+rmax[rs]; 63 rmax[rs]=sum[rs]+tem; 64 mul[ls]*=-1;mul[rs]*=-1; 65 reset[ls]*=-1;reset[rs]*=-1;//這裏忘記寫了 66 mul[x]=1; 67 } 68 } 69 void zig(int x){ 70 int old=fa[x],oldf=fa[old]; 71 tagdown(old); 72 tagdown(x); 73 bool p=get(x); 74 if(oldf)ch[oldf][get(old)]=x; 75 fa[x]=oldf; 76 fa[ch[old][p]=ch[x][p^1]]=old; 77 fa[ch[x][p^1]=old]=x; 78 update(old); 79 update(x); 80 } 81 void splay(int x,int aim=0){ 82 for(int f;(f=fa[x])!=aim;zig(x)) 83 if(fa[f]!=aim)zig(get(x)==get(f)?f:x); 84 if(!aim)rt=x; 85 } 86 int build(int l,int r){ 87 if(l>r)return 0; 88 if(!rt)rt=mid; 89 int Ls=build(l,mid-1); 90 int Rs=build(mid+1,r); 91 if(Ls)fa[ch[mid][0]=Ls]=mid; 92 if(Rs)fa[ch[mid][1]=Rs]=mid; 93 mul[mid]=1; 94 rev[mid]=0; 95 reset[mid]=0; 96 update(mid); 97 return mid; 98 } 99 int kth(int x,int ned){ 100 tagdown(x); 101 if(siz[ls]+1==ned)return x; 102 if(ned<siz[ls]+1)return kth(ls,ned); 103 else return kth(rs,ned-siz[ls]-1); 104 } 105 void out(int x){ 106 tagdown(x); 107 printf("%d %d %d\n",x,ls,rs); 108 if(ls)out(ls); 109 if(rs)out(rs); 110 } 111 int main() 112 { 113 freopen("brackets.in","r",stdin); 114 freopen("brackets.out","w",stdout); 115 // freopen("1.txt","r",stdin); 116 scanf("%d%d",&n,&m); 117 scanf("%s",s); 118 for(int i=2;i<=n+1;i++){ 119 if(s[i-2]==))v[i]=-1; 120 else v[i]=1; 121 } 122 n+=2; 123 build(1,n); 124 for(int i=1;i<=m;i++){ 125 scanf("%s",s); 126 int a,b; 127 scanf("%d%d",&a,&b); 128 a++;b++; 129 a=kth(rt,a-1); 130 b=kth(rt,b+1); 131 splay(a); 132 splay(b,rt); 133 int o=ch[b][0]; 134 if(s[0]==R){ 135 char c; 136 getchar(); 137 c=getchar(); 138 if(c==))reset[o]=-1; 139 else reset[o]=1; 140 sum[o]=reset[o]*siz[o]; 141 if(reset[o]>0)lmax[o]=rmax[o]=siz[o]; 142 else lmax[o]=rmax[o]=0; 143 } 144 if(s[0]==S){ 145 rev[o]^=1; 146 swap(ch[o][0],ch[o][1]); 147 swap(lmax[o],rmax[o]); 148 } 149 if(s[0]==I){ 150 // out(rt); 151 mul[o]*=-1;//printf("%d\n",reset[o]); 152 reset[o]*=-1;//這裏的操作可以保證tagdown中reset存在的情況下其他操作無需執行 153 sum[o]*=-1; 154 int tem=lmax[o]; 155 lmax[o]=sum[o]+rmax[o];//這個數一定是非負的 156 rmax[o]=sum[o]+tem; 157 } 158 if(s[0]==Q){ 159 // printf("%d %d %d\n",lmax[o],rmax[o],sum[o]); 160 printf("%d\n",(rmax[o]-sum[o]+1)/2+(rmax[o]+1)/2);//上取整 161 } 162 } 163 return 0; 164 }
View Code

cogs1279 括號修復