兩題都是樸素想法列舉兩個端點o(n^2)超時,那麼列舉其中乙個端點用線段樹維護另乙個端點。關鍵在於沒插入乙個端點後都是成段更新,否則又會退化到o(n^2)。
ps:兩題用c++交都比g++快500ms以上。
//#include#include#include#include#include#includeusing namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn=50005;
int tree[maxn<<2],lz[maxn<<2];
void pushdown(int rt)
void update(int l,int r,int val,int l,int r,int rt)
int mid=(l+r)>>1;
if(r<=mid)
if(l>mid)
pushdown(rt);
update(l,r,val,lson);
update(l,r,val,rson);
tree[rt]=max(tree[rt<<1],lz[rt<<1]);
tree[rt]=max(tree[rt],max(tree[rt<<1|1],lz[rt<<1|1]));
}int query(int l,int r,int l,int r,int rt)
int mid=(l+r)>>1;
pushdown(rt);
if(r<=mid)
if(l>mid)
return max(query(l,r,lson),query(l,r,rson));
}int a[maxn];
struct qyy
qyy(int a,int b,int c)
bool operator< (const qyy &a) const
void update(int l,int r,int val,int l,int r,int rt)
pushdown(rt);
int mid=(l+r)>>1;
if(r<=mid)
if(l>mid)
update(l,r,val,lson);
update(l,r,val,rson);
}int query(int pos,int l,int r,int rt)
int mid=(l+r)>>1;
pushdown(rt);
if(pos<=mid)
return query(pos,lson);
else
return query(pos,rson);
}bool hash[maxn];
int a[maxn];
struct qyy
qyy(int a,int b,int c)
bool operator< (const qyy& a) const
{return r
hdu 4638 Group 單點修改和離線線段樹
跟hdu4630如出一轍,但是思想上還是要有特別技巧 對於 l,r 上的數a i 我們給乙個標記mark i 表示第第i個數屬於某個連續區間 初始時都賦值為0 pos a i 表示值為a i 的數所在位置 當遇到情況 a i 1 或 a i 1 曾經 出現過時,mark pos a i 1 1 或 ...
hdu 4638 樹狀陣列
思路 將查詢區間按右節點的公升序排列,然後插入第i個數的時候,若nun i 1已經插入,那麼就update pre num i 1 1 pre表示的是該數的位置。同樣若 num i 1存在就update pre num i 1 1 因為他麼與num i 屬於一組,故只需乙個存在就行。當查詢的右邊界r...
hdu4638 Group(樹狀陣列)
題目大意 給乙個1 n的排列,然後詢問 x,y 區間中有多少個連續的段。如給乙個3 1 2 5 4,查詢是2 4,那麼就是問1 2 5中有多少個連續的串,一共有兩個串,1 2為乙個串,5為乙個串 若查詢是2 5,則問的是1 2 5 4中有多少個連續的串,一共有兩個串,1 2為乙個串,4 5 為乙個串...