有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,對...