BZOJ1858 序列操作(線段樹)

2021-08-16 21:09:36 字數 1728 閱讀 5456

bzoj

這題思路很簡單,細節很煩,很碼

維護區間翻轉和區間賦值標記

當打到區間賦值標記時直接覆蓋掉翻轉標記

下放標記的時候先放賦值標記再放翻轉標記

這樣可以維護前4個操作

對於第5個操作

維護區間從左/右端點開始的最大連續0/

1 的個數

以及區間內的最大連續0/

1 的個數

做區間翻轉的時候所有的關於0/

1 連續個數的計數全部要交換過來

其他的細節自己注意一下

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define ll long long

#define rg register

#define max 120000

#define lson (now<<1)

#define rson (now<<1|1)

inline

int read()

int n,m;

struct node

void len1()

void rev()

void clear()

}t[max<<2];

node operator+(node a,node b)

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

int mid=(l+r)>>1;

build(lson,l,mid);build(rson,mid+1,r);

t[now]=t[lson]+t[rson];

}void putrev(int now,int l,int r)

void puteql(int now,int l,int r,int w)

void pushdown(int now,int l,int r)

if(t[now].tag2)

}void modify_eql(int now,int l,int r,int w)

pushdown(now,t[now].l,t[now].r);

int mid=(t[now].l+t[now].r)>>1;

if(l<=mid)modify_eql(lson,l,r,w);

if(r>mid)modify_eql(rson,l,r,w);

t[now]=t[lson]+t[rson];

}void modify_rev(int now,int l,int r)

pushdown(now,t[now].l,t[now].r);

int mid=(t[now].l+t[now].r)>>1;

if(l<=mid)modify_rev(lson,l,r);

if(r>mid)modify_rev(rson,l,r);

t[now]=t[lson]+t[rson];

}int query_sum(int now,int l,int r)

node query_one(int now,int l,int r)

int main()

return

0;}

BZOJ 1858 序列操作 線段樹

題意 給乙個01序列,有5種操作 1 0 l r 將 l,r 之間的數字都變成0 2 1 l r 將 l,r 之間的數字都變成1 3 2 l r 將 l r 之間的數字都取反 4 3 l r 詢問 l r 之間1的個數 5 4 l r 詢問 l,r 之間連續1的個數最大是多少 思路 1 每個節點資訊...

bzoj1858 序列操作 (線段樹區間資訊合併)

1858 scoi2010 序列操作 time limit 10 sec memory limit 64 mb description lxhgww最近收到了乙個01序列,序列裡面包含了n個數,這些數要麼是0,要麼是1,現在對於這個序列有五種變換操作和詢問操作 0 a b 把 a,b 區間內的所有數...

bzoj1858SCOI 序列操作 (線段樹)

題目大意 給定乙個長度為n的01序列為,現在有m種操作 0a b 0ab 把 a,b a,b 的數全部修改為0 1a b 1ab 把 a,b a,b 的數全部修改為1 2a b 2ab 把 a,b a,b 的所有數取反,就是0 1 1 0 3a b 3ab 詢問 a b a,b 中一共有多少個0 4...