P6492 [COCI2010-2011#6] STEP
題目描述:
給定一個長度為 n n n 的字元序列 a a a ,初始時序列中全部都是字元 L L L。
有 q q q 次修改,每次給定一個 x x x ,若 a x a_x ax 為 L L L ,則將 a x a_x ax 修改成 R R R,否則將 a x a_x ax 修改成 L L L。
對於一個只含字元 L L L , R R R 的字串 S S S,若其中不存在連續的 L L L 和 R R R ,則稱 S S S 滿足要求。
每次修改後,請輸出當前序列 a a a 中最長的滿足要求的連續子串的長度。
輸入格式:
第一行有兩個整數,分別表示序列的長度 n n n 和修改操作的次數 q q q。
接下來 q q q 行,每行一個整數,表示本次修改的位置 x x x。
輸出格式:
對於每次修改操作,輸出一行一個整數表示修改 a a a 中最長的滿足要求的子串的長度。
資料規模:
對於全部的測試點,保證 1 ≤ n , q ≤ 2 × 1 0 5 , 1 ≤ x ≤ n 1\leq n,q\leq 2 \times 10^5 , 1\leq x\leq n 1≤n,q≤2×105,1≤x≤n。
樣例輸入1:
6 2
2
4
樣例輸出1:
3
5
樣例輸入2:
6 5
4
1
1
2
6
樣例輸出2:
3
3
3
5
6
思路:
不難想到 L L L 和 R R R 用 0 和 1 來表示,用線段樹來維護序列
而對於每一個結點,維護五個值 l l l、 r r r、 L a n s Lans Lans、 R a n s Rans Rans、 a n s ans ans
其中 l l l 和 r r r 為該節點的左右端點
L a n s Lans Lans 和 R a n s Rans Rans 為當前區間的最左、右邊開始連續的最長滿足條件的序列
ans為當前區間內的滿足要求的最長序列的長度,而每次更新後直接查詢根結點的 a n s ans ans的值
而對於 a n s ans ans的維護:
它只可能是左右兒子結點的 a n s ans ans之一的值,
即為 T [ p o s ] . a n s = m a x ( T [ p o s < < 1 ] . a n s , T [ p o s < < 1 ∣ 1 ] . a n s ) T[pos].ans = max(T[pos<<1].ans,T[pos<<1|1].ans) T[pos].ans=max(T[pos<<1].ans,T[pos<<1∣1].ans)
而「左兒子的最右端」和「右兒子的最左端」的序列異或值為1時,
則答案還可能為 左兒子的 R a n s Rans Rans加上右兒子的 L a n s Lans Lans的值
即為 T [ p o s ] . a n s = m a x ( T [ p o s < < 1 ] . a n s , T [ p o s < < 1 ∣ 1 ] . a n s , T [ p o s < < 1 ] . R a n s + T [ p o s < < 1 ∣ 1 ] . L a n s ) T[pos].ans = max(T[pos<<1].ans,T[pos<<1|1].ans,T[pos<<1].Rans+T[pos<<1|1].Lans) T[pos].ans=max(T[pos<<1].ans,T[pos<<1∣1].ans,T[pos<<1].Rans+T[pos<<1∣1].Lans)
而對於 L a n s Lans Lans的維護:
若該節點的左兒子的 L a n s Lans Lans不等於它的區間長度,則該節點的 L a n s Lans Lans等於左兒子的 L a n s Lans Lans
若該節點的左兒子的 L a n s Lans Lans等於它的區間長度,則還需判斷「左兒子的最右端」和「右兒子的最左端」序列異或值
若異或值為1時,則為左兒子的 L a n s Lans Lans加上右兒子的 L a n s Lans Lans
即為: T [ p o s ] . L a n s = T [ p o s < < 1 ] . L a n s + T [ p o s < < 1 ∣ 1 ] . L a n s T[pos].Lans=T[pos<<1].Lans+T[pos<<1|1].Lans T[pos].Lans=T[pos<<1].Lans+T[pos<<1∣1].Lans
若異或值為0時,則直接等於左兒子的 L a n s Lans Lans
即為: T [ p o s ] . L a n s = T [ p o s < < 1 ] . L a n s T[pos].Lans=T[pos<<1].Lans T[pos].Lans=T[pos<<1].Lans
對於 R a n s Rans Rans的維護同上所示
程式碼:
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5+5;
struct Tree{
int l,r;
int Lans,Rans;
int ans;
}T[MAXN<<2];
int arr[MAXN];
int N,Q,x;
void build(int pos,int l,int r);
void update(int pos,int x);
int main()
{
scanf("%d%d",&N,&Q);
build(1,1,N);
while(Q--){
scanf("%d",&x);
arr[x]^=1;
update(1,x);
printf("%d\n",T[1].ans);
}
}
void build(int pos,int l,int r)
{
T[pos].l=l; T[pos].r=r;
if(l==r){
T[pos].ans=1;
T[pos].Lans=T[pos].Rans=1;
return;
}
int mid = (l+r)>>1;
build(pos<<1,l,mid);
build(pos<<1|1,mid+1,r);
T[pos].ans=T[pos].Lans=T[pos].Rans=1;
return;
}
void update(int pos,int x)
{
int l=T[pos].l,r=T[pos].r;
if(l==r) return;
int mid = (l+r)>>1;
if(x<=mid) update(pos<<1,x);
else update(pos<<1|1,x);
T[pos].ans=max(T[pos<<1].ans,T[pos<<1|1].ans);
if(arr[T[pos<<1].r]^arr[T[pos<<1|1].l])
T[pos].ans=max(T[pos].ans,T[pos<<1].Rans+T[pos<<1|1].Lans);
if(T[pos<<1].Lans<(T[pos<<1].r-T[pos<<1].l+1))
T[pos].Lans=T[pos<<1].Lans;
else{
if(arr[T[pos<<1].r]^arr[T[pos<<1|1].l])
T[pos].Lans=T[pos<<1].Lans+T[pos<<1|1].Lans;
else T[pos].Lans=T[pos<<1].Lans;
}
if(T[pos<<1|1].Rans<(T[pos<<1|1].r-T[pos<<1|1].l+1))
T[pos].Rans=T[pos<<1|1].Rans;
else{
if(arr[T[pos<<1].r]^arr[T[pos<<1|1].l])
T[pos].Rans=T[pos<<1|1].Rans+T[pos<<1].Rans;
else T[pos].Rans=T[pos<<1|1].Rans;
}
return;
}
相關文章
- React Step by StepReact
- Command 模式 Step by Step模式
- Shell Step by Step (4) —— Cron & Echo
- Promise的實現(step by step)Promise
- Step by Step Data Replication Using Oracle GoldenGateOracleGo
- TIDB DM資料同步step by stepTiDB
- Step by Step 安裝 BizTalk Server 2009Server
- 單步除錯 step into/step out/step over 區別詳解除錯
- ABP應用開發(Step by Step)-下篇
- ABP應用開發(Step by Step)-上篇
- 實時 Linux 抖動分析 Step by stepLinux
- Linkerd 2.10(Step by Step)—多叢集通訊
- Sql Server Linux(Redhat) Distributed Availability Group Setup — step by stepSQLServerLinuxRedhatAI
- 10GR2下建立物理standby STEP BY STEP
- Step-by-step,打造屬於自己的vue ssrVue
- Adaboost Algorithm StepGo
- 深度學習之step by step搭建神經網路深度學習神經網路
- Linkerd 2.10(Step by Step)—使用 Kustomize 自定義 Linkerd 的配置
- Linkerd 2.10(Step by Step)—設定服務配置檔案
- Linkerd 2.10(Step by Step)—4. 如何配置外部 Prometheus 例項Prometheus
- 使用Eclipse 安裝 構建Maven專案 (step-by-step)EclipseMaven
- HTML step 屬性HTML
- 【Step-By-Step】高頻面試題深入解析 / 週刊06面試題
- 【Step-By-Step】高頻面試題深入解析 / 週刊07面試題
- 【Step-By-Step】高頻面試題深入解析 / 週刊04面試題
- 【Step-By-Step】高頻面試題深入解析 / 週刊05面試題
- 【Step-By-Step】高頻面試題深入解析 / 週刊03面試題
- 【Step-By-Step】高頻面試題深入解析 / 週刊01面試題
- 【Step-By-Step】高頻面試題深入解析 / 週刊02面試題
- 阿里雲數倉Dataworks資料匯出到檔案step by step阿里
- Linkerd 2.10(Step by Step)—將 GitOps 與 Linkerd 和 Argo CD 結合使用GitGo
- Linkerd 2.10(Step by Step)—1. 將您的服務新增到 Linkerd
- step1 補充
- 2.4.8 Step 7: 建立spfile
- [完結] Learn Vue 2: Step By Step [Laracasts 免費視訊中文語音]VueAST
- [完結] Learn Vue 2: Step By Step [Laracasts 免費影片中文語音]VueAST
- Linkerd 2.10(Step by Step)—2. 自動化的金絲雀釋出
- Vue.js SSR Step by Step (2) – 一個簡單的同構DEMOVue.js