BZOJ 4811 樹鏈剖分 線段樹

2022-04-30 03:54:07 字數 1820 閱讀 5987

思路:

感覺這題也可神了..

(還是我太弱)

首先發現每一位不會互相影響,可以把每一位分開考慮,然後用樹鏈剖分或者lct維護這個樹

修改直接修改,詢問的時候算出來每一位填0,1經過這條鏈的變換之後得到的值

考慮貪心,從高往低,如果這一位填0可以得到1,那麼填0一定是最優的

否則如果可以填1,就把這一位填為1

複雜度是nklog^2n或者nklogn,只能通過50%的資料

發現可以平行計算這k位,複雜度降為nlog^2n的樹鏈剖分或者nlogn的lct,可以通過100%的資料

這個題沒有卡常,合併資訊不是o( 1 )的演算法沒有通過是很正常的吧。。。

還有樹鏈剖分沒法做到logn,每條鏈建線段樹也是log^2n的,還不能搞子樹,似乎常數也一般。。。

最優複雜度是log^2n,不過期望下大概是lognloglogn的感覺

這個題的最優複雜度為o( n + q( logn + k ) ),至少目前來說是這樣的

from 洛谷的題解.

unsigned long long +各種位運算

線段樹要分別維護向上的和向下的

//

by siriusren

#include #include

#include

using

namespace

std;

const

int n=100005

;typedef unsigned

long

long

ull;

ull a[n],zz,now,ans;

int n,m,k,op,xx,yy,op[n],first[n],next[n*2],v[n*2

],tot;

intsize[n],fa[n],son[n],deep[n],rev[n],dfn[n],cnt,top[n];

struct

tree

tree(

int op,ull x)

tree(ull x,ull y)

}trl[n*8],trr[n*8

];tree

operator+(tree x,tree y)

void add(int x,int y)

void dfs(intx)}

void dfs2(int x,int

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

pos)

int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1

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

,r,rson);

trl[pos]=trl[lson]+trl[rson],trr[pos]=trr[rson]+trr[lson];

}void insert(int l,int r,int pos,int

num)

int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1

;

if(mid1

,r,rson,num);

else

insert(l,mid,lson,num);

trl[pos]=trl[lson]+trl[rson],trr[pos]=trr[rson]+trr[lson];

}tree query(

int l,int r,int pos,int l,int r,intf)}

tree solve(

int x,int

y)int

main()

}}

BZOJ 2243 樹鏈剖分 線段樹

include define n 101000 define frei freopen in.txt r stdin define freo freopen out.txt w stdout define mem a,b memset a,b,sizeof a define lson root 1 ...

BZOJ 3531(樹鏈剖分 線段樹)

problem 旅行 bzoj 3531 題目大意 給定一顆樹,樹上的每個點有兩個權值 x,y 要求維護4種操作 操作1 更改某個點的權值x。操作2 更改某個點的權值y。操作3 求a b路徑上所有x屬性與a,b相同的點y屬性的和。操作4 求a b路徑上所有x屬性與a,b相同的點y屬性的最大值。n,q...

BZOJ2243 樹鏈剖分 線段樹)

problem 染色 bzoj2243 題目大意 給定一顆樹,每個節點上有一種顏色。要求支援兩種操作 操作1 將a b上所有點染成一種顏色。操作2 詢問a b上的顏色段數量。解題分析 樹鏈剖分 線段樹。開乙個記錄型別,記錄某一段區間的資訊。l 表示區間最左側的顏色 r 表示區間最右側的顏色 sum ...