題目描述:
給你乙個無限長的陣列,初始的時候都為0,有3種操作:
操作1是把給定區間[l,
r]'>[l,r]
[l,r] 設為1,
操作2是把給定區間[l,
r]'>[l,r]
[l,r] 設為0,
操作3把給定區間[l,
r]'>[l,r]
[l,r] 0,1反轉。[l
,r]'>一共n個操作,每次操作後要輸出最小位置的0。
[l,
r]'>題解:
[l
,r]'>經過分析觀察,可以發現,答案只有可能是[l
,r]'>1,l
,r+1
'>1,l,r+1
[l,
r]'>1,l
,r+1
'>
[l
,r]'>1,l
,r+1
'>所以我們開乙個陣列記錄1,以及所有的l,r,r+1,並離散化[l
,r]'>1,l
,r+1
'>然後用線段樹模擬操作即可[l
,r]'>1,l
,r+1
'>這裡有兩種思路:[l
,r]'>1,l
,r+1
'>一種是記錄某一區間內0的最小位置和1的最小位置,反轉時互換兩個位置
#include#include#include
using
namespace
std;
typedef
long
long
ll;const
int n=1e5+5
;const
int maxn=3e5+5
;int
n,m;ll a[maxn];
struct
queq[n];
int s0[maxn<<2],s1[maxn<<2],lazy[maxn<<2],rev[maxn<<2
];void pushup(int
u)void build(int u,int l,int
r)
int mid=(l+r)/2
; build(u*2
,l,mid);
build(u*2+1,mid+1
,r);
pushup(u);
}void pushdown(int u,int l,int
r)
else
if(lazy[u]==0
) lazy[u]=-1
; }
if(rev[u])
}void update(int u,int l,int r,int a,int b,int
k) pushdown(u,l,r);
int mid=(l+r)/2
;
if(a<=mid) update(u*2
,l,mid,a,b,k);
if(b>mid) update(u*2+1,mid+1
,r,a,b,k);
pushup(u);
}void revere(int u,int l,int r,int a,int
b) pushdown(u,l,r);
int mid=(l+r)/2
;
if(a<=mid) revere(u*2
,l,mid,a,b);
if(b>mid) revere(u*2+1,mid+1
,r,a,b);
pushup(u);
}int
main()
sort(a+1,a+n+1
); n=unique(a+1,a+1+n)-a-1
; build(
1,1,n);
for(int i=1;i<=m;i++)
else
if(q[i].op==2
)
else
if(!s0[1]) printf("
%lld\n
",a[n]+1
);
else printf("
%lld\n
",a[s0[1
]]);
}return0;
}
另一種是記錄某一區間內1的個數,查詢時如果乙個區間內1的個數小於這個區間的總個數,則說明這個區間內有0,遞迴下去
#include#include#include
using
namespace
std;
typedef
long
long
ll;const
int n=1e5+5
;const
int maxn=3e5+5
;int
n,m;ll a[maxn];
struct
queq[n];
int sum[maxn<<2],lazy[maxn<<2],rev[maxn<<2
];void build(int u,int l,int
r)void pushdown(int u,int l,int
r)
else
lazy[u]=-1
; }
if(rev[u])
//還是錯誤2
}void update(int u,int l,int r,int a,int b,int
p)
else
else
if(p==2
)
else
//錯誤2:lazy,rev是會相互影響的
}
return
; }
pushdown(u,l,r);
int mid=(l+r)/2
;
if(a<=mid) update(u*2
,l,mid,a,b,p);
if(b>mid) update(u*2+1,mid+1
,r,a,b,p);
sum[u]=sum[u*2]+sum[u*2+1];}
ll query(
int u,int l,int
r)int
main()
sort(a+1,a+n+1
); n=unique(a+1,a+1+n)-a-1
; build(
1,1,n);
for(int i=1;i<=m;i++)
return0;
}
離散化 線段樹
題目 分析 每次1操作會往序列底加first個second,first 和 second 都是最大1e9的資料,每次2操作詢問序列中第first到第second個數的和 一開始就感覺有點像線段樹,輸入資料太大我們可以離線處理把資料離散化下,然後扔到線段樹上,維護兩個陣列 sum 區間數的值的和 nu...
資料離散化 線段樹
前言 遇到了乙個矩形面積堆疊的問題,想了很久。終於找到了方法。先做個小記,待到具體問題時再分析。資料離散化 高大上的名字,其實就是對資料的一種處理,也可以採取陣列 或者 容器 map vector。之類的來儲存。之前的ibm技術俱樂部主席競選 那道題其實就是很好的應用。有些資料本身很大,自身無法作為...
紙帶 線段樹 離散化
題目大意 每次給一段區間染色,求最後整個區間有多少種顏色 分析 用膝蓋想也知道這題線段樹可以輕鬆水過,於是出題人靈機一動,挖了個深坑,每次給的區間是左開右閉的,但題目沒說,他給了你一張圖,你們可以感受一下 於是正解wa成0分我也是很絕望的。有一點要注意一下,離散化後有些區間會並在一起,原來中間的顏色...