E Let Them Slide 線段樹騷操作

2021-09-28 19:30:44 字數 1735 閱讀 4855

e. let them slide

題意:就是每行可能有可滑動的一行資料,詢問每列的最大和。

題解:我們維護一行資料的每個位置對固定一行位置的貢獻,可滑動的資料可以對固定的多個位置有貢獻,所以我們維護一顆可以區間更新最大值和最小值的線段樹,然後再維護乙個sum[o]陣列,代表那一段區間的最優解sum[o]當mx[o]==mn[o]時就停止向下更新了,因為如果mx[o]==mn[o]就代表那個區間的最大值都是mx[o]。那麼我們查詢只要查詢到每個位置,然後沿路將值相加。

#include

#define ll long long

#define m (l+r)/2

#define ls o*2

#define rs o*2+1

using

namespace std;

const

int maxn =

1e6+10;

ll sum[maxn*4]

;int mn[maxn*4]

,mx[maxn*4]

,lz[maxn*4]

,vis[maxn*4]

;int inf =

1e9+1;

vector<

int>g;

void

add(

int o)

void

pushup

(int o,

int l,

int r)

void

pushdown

(int o,

int l,

int r)

}voidup(

int o,

int l,

int r,

int ql,

int qr,

int v)

pushdown

(o,l,r);if

(mn[ls]

up(ls,l,m,ql,qr,v);if

(mn[rs]

up(rs,m+

1,r,ql,qr,v)

;pushup

(o,l,r)

;return;}

pushdown

(o,l,r);if

(ql<=m)

up(ls,l,m,ql,qr,v);if

(qr>m)

up(rs,m+

1,r,ql,qr,v)

;pushup

(o,l,r);}

ll qu

(int o,

int l,

int r,

int k)

void

cul(

int o,

int l,

int r)

cul(ls,l,m)

;cul

(rs,m+

1,r);}

intmain()

if(lcul(1,

1,w)

;for

(auto v:g) mn[v]

= mx[v]

= lz[v]

=-inf,vis[v]=0

; g.

clear()

;}for(

int i=

1;i<=w;i++

)printf

("%lld\n",qu

(1,1

,w,i));

}

D 線段線段

x軸上有n條線段,每條線段包括1個起點和終點。線段的重疊是這樣來算的,10201020和12251225的重疊部分為12201220。給出n條線段的起點和終點,從中選出2條線段,這兩條線段的重疊部分是最長的。輸出這個最長的距離。如果沒有重疊,輸出0。input 第1行 線段的數量n 2 n 5000...

2018 08 18 線段樹(線段樹)

線段樹 描述請你維護乙個線段樹 支援一下操作 a x l r 區間 and x o x l r區間 or x x x l r 區間 xor x s l r 區間求和 輸入乙個數 t表示資料組數 乙個數n表示初始序列長 m表示查詢 隨後n個整數 接下來m次詢問 如上 輸出所以s次詢問的答案 樣例輸入 ...

刪除多餘線段 線段樹

2020 3 24 更新 一,簡介 二,作用及原理 三,線段樹中最重要的 延遲標記 四,額外說明 五,具體實現 一,簡介線段樹,一種樹狀資料結構,顧名思議,樹的每乙個節點儲存的是線段的某種資訊,因此,你需要宣告乙個結構體來代表樹上的每乙個節點,最基本的資訊有線段的左端點,右端點,常用的有線段區間的元...