【線段樹提高】51nod &&洛谷
兩個線段樹很好的題目
NO.1 51nod 1426 沙拉醬括號
好多都用字首和+二分 我覺得線段樹可行做了一下 就是要用vc++ 交C語言 不然會t
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<cstring>
//using namespace std;
#define maxn 8000000+100
int aa[maxn];
int min(int x,int y){
if(x>=y) return y;
return x;
}
struct ac{
int s,l,r;
ac(){
s=0;l=0,r=0;
}
ac(int a,int b,int c){
s=a,l=b,r=c;
}
}a[maxn*4];
void build(int l,int r,int in){
if(l==r){
if(aa[l]==1)
a[in]=ac(0,1,0);
else a[in]=ac(0,0,1);
return ;
}
int mid=(l+r)/2;
build(l,mid,in*2);
build(mid+1,r,in*2+1);
int lson=in*2,rson=in*2+1;
int x=min(a[lson].l,a[rson].r);
int y=a[lson].l-x;int z=a[rson].r-x;
int s=a[lson].s+a[rson].s+x;
a[in]=ac(s,y+a[rson].l,a[lson].r+z);
}
ac query(int l,int r,int L,int R,int in){
if(l==L&&r==R){
return a[in];
}
int mid=(l+r)/2;
if(L>mid){ //這個地方一定要處理好 因為我返回的是結構體所以返回的含有這個區間左右括號的資訊
return query(mid+1,r,L,R,in*2+1);
}else if(R<=mid){
return query(l,mid,L,R,in*2);
}
ac b=query(l,mid,L,mid,in*2);
ac c=query(mid+1,r,mid+1,R,in*2+1);
int x=min(b.l,c.r);
int y=b.l-x;int z=c.r-x;
int k=b.s+c.s+x;
return ac(k,y+c.l,b.r+z);
}
int main(){
char s[maxn*10];
scanf("%s",s);
int n;
scanf("%d",&n);
int len=strlen(s);
for(int j=0;j<len;j++){
if(s[j]=='(')
aa[j+1]=1;
else aa[j+1]=-1;
}
build(1,len,1);
for(int j=0;j<n;j++){
int l,r;
scanf("%d%d",&l,&r);
ac b=query(1,len,l,r,1);
printf("%d\n",b.s*2);
}
return 0;
}
洛谷 3797 妖夢斬木棒
#include<bits/stdc++.h>
using namespace std;
#define maxn 600000+100//結構體消耗記憶體好大 我開了這麼大才可以 小的話後面的資料全部 re
struct ac{
int s,l,r; //(l=='(' r==')';
ac(){
s=0;
l=0;
r=0;
}
ac(int a,int b,int c){
s=a;
l=b;
r=c;
}
}a[maxn*4];
int n,m;
void updata(int l,int r,int in,int va,int v){
if(r<1|r>n) return ;
if(l==r){
if(v==1) a[in]=ac(0,1,0);
if(v==2) a[in]=ac(0,0,1);
if(v==3) a[in]=ac(0,0,0); //更新不多解釋
return ;
}
int mid=(l+r)/2;
if(va>mid){
updata(mid+1,r,in*2+1,va,v);
}else{
updata(l,mid,in*2,va,v);
}
int x=a[in*2].s+a[in*2+1].s;
int y=a[in*2].l+a[in*2+1].r; // 看左右能否組成一個完整的括號
if(y==2){
a[in]=ac(x+1,a[in*2+1].l,a[in*2].r); //可以組成採用右兒子的左括號,左兒子的右括號
}else{
if(x!=0){ //當他們存在完整的括號對時
if(a[in*2].s==0&&a[in*2].r==0){ // 完整的括號對在右區間的時候
a[in]=ac(x,a[in*2+1].l,a[in*2+1].r);
}else if(a[in*2+1].s==0&&a[in*2+1].l==0){ //在左區間的時候
a[in]=ac(x,a[in*2].l,a[in*2].r);
}
else a[in]=ac(x,a[in*2+1].l,a[in*2].r); //左右區間都存在
}
else a[in]=ac(x,a[in*2+1].l|a[in*2].l,a[in*2+1].r|a[in*2].r);//左右都不存在
}
}
ac query(int l,int r,int L,int R,int in){
if(l==L&&r==R){
return a[in];
}
int mid=(l+r)/2;
if(L>mid){ //這個地方一定要處理好 因為我返回的是結構體所以返回的含有這個區間左右括號的資訊
return query(mid+1,r,L,R,in*2+1);
}else if(R<=mid){
return query(l,mid,L,R,in*2);
}
//下面和更新操作的一樣
ac b=query(l,mid,L,mid,in*2);
ac c=query(mid+1,r,mid+1,R,in*2+1);
int x=b.s+c.s;
int y=b.l+c.r;
if(y==2){
return ac(x+1,c.l,b.r);
}
if(x!=0){
if(b.s==0&&b.r==0){
return ac(x,c.l,c.r);
}else if(c.s==0&&c.l==0){
return ac(x,b.l,b.r);
}
return ac(x,a[in*2+1].l,a[in*2].r);
}
return ac(x,c.l|b.l,c.r|b.r);
}
int main(){
// FILE *fp;
// fp=fopen("C://Users//Dcoder//Desktop//1.txt","r+");
cin>>n>>m;
//build(1,n,1);
updata(1,n,1,1,1);//相當於兩次更新 一次開頭 一次結尾
updata(1,n,1,n,2);
while(m--){
int x;
cin>>x;
if(x==2){
int l,r;
cin>>l>>r;
// fprintf(fp,"%d\n",query(1,n,l,r,1).s);
cout<<query(1,n,l,r,1).s<<endl;
}else{
char c;
int y;
cin>>y>>c;
if(c=='X'){
updata(1,n,1,y,3);
}else if(c=='('){
updata(1,n,1,y,1);
}else{
updata(1,n,1,y,2);
}
}
}
//fclose(fp);
return 0;
}
相關文章
- 洛谷題單指南-線段樹-P3373 【模板】線段樹 2
- 洛谷題單指南-線段樹-P1471 方差
- 可持久化線段————主席樹(洛谷p3834)持久化
- 洛谷P4425 [HNOI/AHOI2018]轉盤(線段樹)
- 洛谷P4069 [SDOI2016]遊戲(李超線段樹)遊戲
- 洛谷 P3919 可持久化線段樹 1 之主席樹模板(初級)持久化
- 洛谷題單指南-線段樹-P1253 扶蘇的問題
- 洛谷P3586 [POI2015]LOG(貪心 權值線段樹)
- 洛谷P1712 [NOI2016]區間 尺取法+線段樹+離散化
- 洛谷P2178 [NOI2015]品酒大會(字尾自動機 線段樹)
- 洛谷 - P6292 區間本質不同子串個數(SAM+LCT+線段樹)
- 洛谷-P1250 種樹
- 洛谷P1087 FBI樹
- 洛谷P3369 普通平衡樹(Splay)
- 洛谷P4197 Peaks(Kruskal重構樹 主席樹)
- 洛谷P4632 [APIO2018] New Home 新家(動態開節點線段樹 二分答案 掃描線 set)API
- 線段樹
- 線~段~樹
- 洛谷P3369 普通平衡樹之板子
- 洛谷 P4913 二叉樹深度二叉樹
- 洛谷 P5350 序列 珂朵莉樹
- 洛谷
- 51nod“省選”模測第二場 C 小朋友的笑話(線段樹 set)
- 01 線段樹
- 線段樹--RMQMQ
- 【模版】線段樹
- 線段樹模板
- 線段樹 hate it
- 二叉樹 遞迴 洛谷P1364二叉樹遞迴
- [藍橋杯][演算法提高VIP]分蘋果 線段樹演算法蘋果
- 【51nod】最大子段和
- 洛谷P1039 [NOIP2003 提高組] 偵探推理
- 洛谷P1563 [NOIP2016 提高組] 玩具謎題
- 洛谷 P1004 [NOIP2000 提高組] 方格取數
- 洛谷 P1006 [NOIP2008 提高組] 傳紙條
- ut.cpp 最大線段並減線段交 [線段樹]
- 洛谷 P2590 [ZJOI2008]樹的統計
- 李超線段樹