HDU 5324(分治 樹狀陣列)

2021-07-04 04:51:15 字數 1411 閱讀 7899

本題目的原來意思是,給定兩個長度為n的陣列,l,r,要求乙個子串行(可以不連續)使的l遞減,r遞增。

分析:加上下標遞增,兩個維度增,乙個減,那麼考慮  d[ i ]代表以i為起點的串往後找能得到的最大長度,用分治方法更新最有值。那麼下面說一下,怎麼分治維護最優。

首先,陣列原順序保持不變,就是下標遞增,對於l - > r區間的每個點的最優值,先求出右半區間每個點的最優值,然後把左右區間分別以r值增序排序,那麼就可以用樹狀陣列,來更新左半區間的d值,這樣消除了右半區間對左半區間的影響,然後再求左半區間的最優值即可。

#include #include #include #include #include #include #include #include #include#include using namespace std;

#define rep(i,n) for(int i=0;i<(int)n;i++)

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

#define lowbit(x) (x&(-x))

#define pii(x,y) make_pair(x,y)

typedef pairpii;

const int n = 51010;

const int inf = 0x3f3f3f3f;

struct node

int get(int x)

}sl,sr;

struct bit

return res;

}}bit;

pii d[n];

void solve(int l,int r)

pii can=bit.query(tem[i].l);

d[tem[i].id]=max(d[tem[i].id],can);

}for(int i=m+1;i<=r;i++) bit.modify(tem[i].l,pii(0,-n));

solve(l,m);

}int n;

void read()

rep1(i,1,n)

sl.prepare(); sr.prepare();

rep1(i,1,n)

rep(i,n) bit.c[i]=pii(0,-n);

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

solve(1,n);

int ans=-1,cnt=0,p;

rep1(i,1,n)

}printf("%d\n",ans);

for(int i=p;i!=(-n);i=d[i].second)

printf("\n");

}int main()

return 0;}/*

43 2 1 1

2 3 1 1

*/

HDU4918 點分治 樹狀陣列

叉姐的題 看了看聊天記錄發現自己光調就是至少兩個多小時.不過慢慢來吧 嚴格意義上講是自從上學期final week以來復健的第一道大資料結構題.其實寒假因為突擊駕照的緣故也荒廢掉很多時間.題意其實很簡明扼要 兩種操作 改變樹上某個點的權值 或者 詢問在某個點d距離範圍內的所有權值和 其實不論考不考慮...

分狀態的樹狀陣列hdu 4267

我們用tree v k mod 來表示樹狀陣列的狀態。假如a b c k,那麼用樹狀陣列,區間更新,update b,a k,k,c update a 1,a k,k,c 就可以了 也就是說,區間 1,b 內每個ui k mod 那麼ui 的值就加c 然後 1,a 1 區間內每乙個ui c,於是就完...

HDU2852 樹狀陣列 二分

思路 樹狀陣列是用來標記的!值 區間點!因為這裡值重複是算的,所有樹狀陣列存的是區間上該位置的個數。0 插入則插入。1 if sum x sum x 1 puts no.2 我們知道a 包括a 之前有多少個數x,求第k大的數,也就是求在樹狀陣列中第x k大的數。sum ans x k。這個可以直接二...