HDU 3397 區間覆蓋,顛倒,合併(好題)

2022-09-17 23:48:16 字數 3275 閱讀 5690

三個操作

[a,b]覆蓋為0

[a,b]覆蓋為1

[a,b]顛倒每項

兩個查詢

[a,b]間1數量

[a,b]間最長連續1數量

其實是區間覆蓋,區間顛倒和區間合併的結合,可以先看這幾道題

區間合併:

區間更新(兩種更新方式):

可以分為兩項做:

1的數量很簡單,用len儲存每個區間數量即可

[a,b]區間內最長連續其實之前沒做過,具體做法是:

在區間合併的基礎上,在query時取左子樹,右子樹以及min(mid-l+1,rsum[ls])+min(r-mid,lsum[rs])的最小值

這裡的min(mid-l+1,rsum[ls])+min(r-mid,lsum[rs])其實就是左子樹的右端和右子樹左端結合,前面那項是為了限定左右的最大值,因為要在選定的區間內找連續值

#include #include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define mem(a,b) memset(a,b,sizeof(a))

#define pf printf

#define sf scanf

#define spf sprintf

#define pb push_back

#define debug printf("!\n")

#define maxn 100000+5

#define max(a,b) a>b?a:b

#define blank pf("\n")

#define ll long long

#define all(x) x.begin(),x.end()

#define ins(x) inserter(x,x.begin())

#define pqueue priority_queue

#define inf 0x3f3f3f3f

#define ls (rt<<1)

#define rs (rt<<1|1)

intn,m;

int col[maxn<<3],a[maxn<<3],len[maxn<<3

];int sum[maxn<<3],lsum[maxn<<3],rsum[maxn<<3],mz[maxn<<3],lz[maxn<<3],rz[maxn<<3

];void cg(int &a,int &b)

void fxor(int rt,int

k)

else col[rt]^=1;}

void pushdown(int rt,int l,int

r)

if(col[rt])

col[rt] = 0

; }

}void pushup(int rt,int

k)void build(int l,int r,int

rt)void update(int val,int l,int r,int l,int r,int

rt)

else

if(val==1

)

else

return

; }

pushdown(rt,l,r);

int mid = (l+r)>>1

;

if(l <=mid) update(val,l,r,l,mid,ls);

if(r > mid) update(val,l,r,mid+1

,r,rs);

pushup(rt,r-l+1);}

ll ans = 0;//

統計1數量

void query(int l,int r,int l,int r,int

rt) pushdown(rt,l,r);

int mid = (l+r)>>1

;

if(l<=mid) query(l,r,l,mid,ls);

if(r>mid) query(l,r,mid+1

,r,rs);}//

最長連續1

int query2(int l,int r,int l,int r,int

rt) pushdown(rt,l,r);

int res = 0

;

int mid = (l+r)>>1

;

if(l<=mid)

if(r>mid)

res = max(res,min(mid-l+1,rsum[ls])+min(r-mid,lsum[rs]));

return

res;

}int

main()

//for(i=1;i<=18;i++) pf("t%d %d %d %d\n",i,sum[i],lsum[i],rsum[i]);

//for(i=1;i<=18;i++) pf("t%d %d %d %d\n",i,mz[i],lz[i],rz[i]);

for(i=1;i<=m;i++)

else

//for(j=1;j<=18;j++) pf("t%d %d %d %d t%d %d\n",j,sum[j],lsum[j],rsum[j],a[j],col[j]);

//for(j=1;j<=18;j++) pf("tt%d %d %d %d\n",j,mz[j],lz[j],rz[j]);

} }

return0;

}/*110 1000

0 0 0 1 1 0 1 0 1 1

3 0 0

3 1 1

3 2 2

3 3 3

3 4 4

3 5 5

3 6 6

3 7 7

3 8 8

3 9 9

3 0 0

3 0 1

3 0 2

3 0 3

3 0 4

3 0 5

3 0 6

3 0 7

3 0 8

3 0 9

*/

7620 區間合併

7620 區間合併 總時間限制 1000ms 記憶體限制 65536kb 描述 給定 n 個閉區間 ai bi 其中i 1,2,n。任意兩個相鄰或相交的閉區間可以合併為乙個閉區間。例如,1 2 和 2 3 可以合併為 1 3 1 3 和 2 4 可以合併為 1 4 但是 1 2 和 3 4 不可以合...

7620 區間合併

總時間限制 1000ms 記憶體限制 65536kb 描述 給定 n 個閉區間 ai bi 其中i 1,2,n。任意兩個相鄰或相交的閉區間可以合併為乙個閉區間。例如,1 2 和 2 3 可以合併為 1 3 1 3 和 2 4 可以合併為 1 4 但是 1 2 和 3 4 不可以合併。我們的任務是判斷...

7620 區間合併

總時間限制 1000ms 記憶體限制 65536kb 描述給定 n 個閉區間 ai bi 其中i 1,2,n。任意兩個相鄰或相交的閉區間可以合併為乙個閉區間。例如,1 2 和 2 3 可以合併為 1 3 1 3 和 2 4 可以合併為 1 4 但是 1 2 和 3 4 不可以合併。我們的任務是判斷這...