bzoj4127 Abs 樹鏈剖分 線段樹

2022-05-01 22:33:17 字數 1468 閱讀 8439

abs bzoj-4127

題目大意:給定一棵數,支援鏈加和鏈上權值的絕對值的和。

注釋:$1\le n,m \le 10^5$,$\delta \ge 0$,$|a_i|\le 10^8$。

想法:看完題,以為又是什麼資料結構裸題。然後發現絕對值... ...臥槽?啥jb玩意兒?絕對值?這怎麼加?開始的想法是維護乙個do標記,表示這個區間有沒有負值,如果沒有直接懶標記,如果有,往下走的時候負數取出來,然後二分治... ...不想寫,上網查的題解。我們先樹鏈剖分之後建線段樹。緊接著我們對於一段區間維護乙個小資訊:maxdown。表示這個點所代表的區間中的所有負值中的最大值的絕對值。我們發現所有的增量都是正的,所以每乙個數的正負號只能變動一次並且只能從負號變成正號。所以在區間修改的時候如果這個區間有負值我們就暴力修改即可。

最後,附上醜陋的**... ...

#include #include #include #include #define n 100010

#define lson l,mid,x<<1

#define rson mid+1,r,x<<1|1

using namespace std;

typedef long long ll;

const int inf=1<<30;

int a[n],head[n],to[n<<1],next[n<<1],cnt,fa[n],deep[n],sv[n],bl[n],pos[n],tot,v[n];

int n,val[n<<2],si[n<<2],add[n<<2];

ll sum[n<<2];

void addedge(int x,int y)

void dfs1(int x)

void dfs2(int x,int c)

}void pushup(int x)

void pushdown(int x)

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

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

build(lson),build(rson);

pushup(x);

}void update(int b,int e,int a,int l,int r,int x)

}ll query(int b,int e,int l,int r,int x)

void modify(int x,int y,int z)

ll solve(int x,int y)

int main()

{ int m,opt,x,y,z;

scanf("%d%d",&n,&m);

for(int i=1;i<=n;i++)scanf("%d",&a[i]);

for(int i=1;i小結:注意題目中的資料範圍,對於一些比較特殊的性質要發掘並利用。

bzoj 4147 Abs 熟練剖分

題目描述 給定一棵樹,設計資料結構支援以下操作 1 u v d 表示將路徑 u,v 加d 2 u v 表示詢問路徑 u,v 上點權絕對值的和 輸入 第一行兩個整數n和m,表示結點個數和運算元 接下來一行n個整數a i,表示點i的權值 接下來n 1行,每行兩個整數u,v表示存在一條 u,v 的邊 接下...

樹鏈剖分 樹鏈剖分講解

好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 vector v maxn int size maxn dep maxn val maxn id maxn hson maxn top maxn fa maxn 定義 int edge 1,num 1 struct tree e ma...

BZOJ 3306 樹 樹鏈剖分

和bzoj 3083比就是弱化版了。樣例都有點像?include include using namespace std const int n 100005,m n 3,inf 0x7fffffff int read int next m to m head n sz n son n top n ...