COGS2638 數列操作

2022-08-22 11:24:11 字數 1784 閱讀 5738

給定乙個數列a,你需要支援的操作:區間and,區間or,詢問區間最大值

一行兩個整數n,m,表示數列長度和操作個數。

接下來一行有n個整數,第i個數表示ai。

接下來m行,每一行均為以下三種操作中的一種

1 l r val:ai=ai and val(l≤i≤r)

2 l r val:ai=ai or val(l≤i≤r)

3 l r:max(l≤i≤r)

對於每乙個3操作,輸出一行整數表示對應的答案

8 6

4 0 5 7 2 9 12 8

2 2 5 15

1 3 5 2

3 5 7

1 5 7 12

2 1 6 4

3 2 6

12

15

對於20%資料,n,m≤3000

另有20%資料,1,2操作中l=r

另有20%資料,3操作中l=r

對於100%資料,1≤n,m≤100000,0≤ai,val≤1e9

保證所有操作中1≤l≤r≤n

區間and操作相當於將區間中所有數的某些位全變成0,區間or操作相當於將區間中所有數的某些位全變成1。

線段樹每個節點維護區間and和以及區間or和,還要維護乙個and標記乙個or標記以及區間最大值。

標記的先後順序是先and後or。

區間操作先找到區間,如果區間中所有的數要修改的那些位已經全相同,直接打上標記後返回。否則遞迴處理子區間。

#include#define maxn 100010

#define inf 0x7fffffff

#define lc rt<<1

#define rc rt<<1|1

namespace io

inline int qr()

while(ch>='0'&&ch<='9')

return rev?-x:x;}

}using namespace io;

using namespace std;

int n,q,tago[maxn<<2],taga[maxn<<2],vo[maxn<<2],va[maxn<<2],ma[maxn<<2],a[maxn];

inline void up(int rt)

inline void putand(int rt,int x)

inline void putor(int rt,int x)

inline void down(int rt)

if(tago[rt])

}void build(int l,int r,int rt)

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

build(l,mid,lc);build(mid+1,r,rc);

up(rt);

}void modify(int l,int r,int l,int r,int rt,int x,bool flag)

} else

} } down(rt);

int mid=l+r>>1;

if(l<=mid)modify(l,r,l,mid,lc,x,flag);

if(r>mid)modify(l,r,mid+1,r,rc,x,flag);

up(rt);

}int query(int l,int r,int l,int r,int rt)

int op,x,y,z;

int main()

return 0;

}

cogs2638 數列操作 雙標記線段樹

題目大意 給定乙個數列a,你需要支援的操作 區間and,區間or,詢問區間最大值 解題關鍵 1 雙標記線段樹,注意優先順序 超時 當涉及多重標記時,定義出標記的優先順序,修改操作時用優先順序高 先下放 的修正優先順序低 後下放 的來保證標記的正確性。同時維護了區間and,區間or include i...

COGS 2964 數列操作

傳送門 題目描述 給定長度均為 n nn 的數列 a,b a,ba,b,其中 b bb 數列為 1 11 n nn 的全排列,a aa 數列全為 000。你需要支援 q qq 次操作,操作分為 add addad d 和 que ry query quer y 兩種。其中 x x x 表示對 x x...

COGS 2632 數列操作d

傳送門 題目描述 乙個長度為 n nn 的序列,一開始序列數的權值都是 0 00,有 m mm 次操作 支援兩種操作 1 11l llrrrx xx,給區間 l ll r rr 內位置為 pos pospo s 的數加上 po s l x pos l x pos l x000l llr rr,查詢區...