bzoj2333 離線 線段樹

2022-05-20 03:01:37 字數 3502 閱讀 8825

有n個節點,標號從1到n,這n個節點一開始相互不連通。第i個節點的初始權值為a[i],接下來有如下一些操作:

u x y: 加一條邊,連線第x個節點和第y個節點

a1 x v: 將第x個節點的權值增加v

a2 x v: 將第x個節點所在的連通塊的所有節點的權值都增加v

a3 v: 將所有節點的權值都增加v

f1 x: 輸出第x個節點當前的權值

f2 x: 輸出第x個節點所在的連通塊中,權值最大的節點的權值

f3: 輸出所有節點中,權值最大的節點的權值

題意看起來像一道可並堆的硬核資料結構題。

實際上確實是一道可並堆的資料結構題。

但我不會

那我有什麼辦法,只能用離線 + 線段樹做了。

離線處理交換位置,保證所有連邊的點都相鄰,然後直接上區間修改+區間查詢。

思路不難,就是寫起來有點煩

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

inline

int read()

#define for(i, x, y) for(int i=x;i<=y;i++)

#define _for(i, x, y) for(int i=x;i>=y;i--)

#define mem(f, x) memset(f,x,sizeof(f))

#define sca(x) scanf("%d", &x)

#define sca2(x,y) scanf("%d%d",&x,&y)

#define sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)

#define scl(x) scanf("%lld",&x);

#define pri(x) printf("%d\n", x)

#define prl(x) printf("%lld\n",x);

#define clr(u) for(int i=0;i<=n;i++)u[i].clear();

#define ll long long

#define ull unsigned long long

#define mp make_pair

#define pii pair#define pil pair#define pll pair#define pb push_back

#define fi first

#define se second typedef vector

vi;const

double eps = 1e-9

;const

int maxn = 3e5 + 10

;const

int inf = 0x3f3f3f3f

;const

int mod = 1e9 + 7

; template

inline

bool scan_d(t &ret)

intn,m,k;

inta[maxn];

struct

nodenode[maxn];

intnxt[maxn],ed[maxn];

intfa[maxn];

int find(int

p)void union(int a,int

b)void

init()

intpos[maxn],id[maxn];

struct

treetree[maxn

<< 2

];void pushup(int

t)void pushdown(intt)}

void build(int t,int l,int

r)

int m = (l + r) >> 1

; build(t

<< 1,l,m); build(t << 1 | 1,m + 1

,r);

pushup(t);

}void update(int t,int l,int r,int

v) pushdown(t);

int m = (tree[t].l + tree[t].r) >> 1

;

if(r <= m) update(t << 1

,l,r,v);

else

if(l > m) update(t << 1 | 1

,l,r,v);

else

pushup(t);

}int query(int t,int l,int

r) pushdown(t);

int m = (tree[t].l + tree[t].r) >> 1

;

if(r <= m) return query(t << 1

,l,r);

else

if(l > m) return query(t << 1 | 1

,l,r);

return max(query(t << 1,l,m),query(t << 1 | 1,m + 1

,r));

}int

main()

else

if(node[i].op[0] == '

a' && node[i].op[1] == '3'

)else

if(node[i].op[0] == 'u'

) union(node[i].x,node[i].y);

}int cnt = 0

;

for(int i = 1; i <= n ; i ++)

}build(

1,1,n); init();

int sum = 0

;

for(int i = 0 ; i < m ; i ++)

if(node[i].op[0] == 'a'

)else

if(node[i].op[1] == '2'

)else

}else

if(node[i].op[0] == 'f'

)else

if(node[i].op[1] == '2'

)else}}

#ifdef vscode

system(

"pause");

#endif

return0;

}

刷題總結 棘手的操作(bzoj2333)

scoi2011 day2 t1 有 n 個節點,標號從 1 到 n 這 n 個節點一開始相互不連通。第i個節點的初始權值為 a i 接下來有如下一些操作 u x y 加一條邊,連線第 x 個節點和第 y 個節點 a1 x v 將第 x 個節點的權值增加 v a2 x v 將第 x 個節點所在的連通...

bzoj 3339 線段樹離線處理

題意 給定乙個n個數的序列,多次詢問,每次詢問區間 l,r 的mex 直接暴力顯然不可 區間 l,r 和區間 l r mex的情況 1 l,r 和 l r 的mex值不同 l,r 的mex值在 l r 中出現 或 原本在 l,r 中存在而不在 l r 中存在從而成為 l r 的mex值 反之同理 2...

BZOJ 3626 離線 樹鏈剖分 線段樹

思路 抄一波yousiki的 顯然,暴力求解的複雜度是無法承受的。考慮這樣的一種暴力,我們把 z 到根上的點全部打標記,對於 l 到 r 之間的點,向上搜尋到第乙個有標記的點求出它的深度統計答案。觀察到,深度其實就是上面有幾個已標記了的點 包括自身 所以,我們不妨把 z 到根的路徑上的點全部 1,對...