HDU 6703 array 權值線段樹

2021-09-26 10:50:29 字數 1411 閱讀 1164

先不考慮修改的情況,對所有的權值建一顆線段樹,然後線段樹上儲存下標的資訊,然後每個結點維護子樹下標的最大值。然後對於每次查詢,我直接查詢區間[k,

n+1]

[k,n+1]

[k,n+1

]這段區間值大於r的最小的那個點。

對於修改的情形,實際上每個節點被修改之後相當於刪除,也就是說該節點是可選的,把該節點的下標置為無窮大就可以了。

對於每次查詢,先考慮查詢左子樹,如果左子樹查詢不到答案,再查詢右子樹,可以證明這個複雜度是o(l

og

)o(log)

o(log)

的。對於查詢的區間全部落在左子樹和右子樹的情形,我們歸納到子樹中。剩下的情況只剩下查詢區間橫跨mid這個中點,對於這種情形,答案不存在左子樹中則必定在右子樹中,而右子樹不會出現無解的情形。

#includeusing namespace std;

typedef long long ll;

const int inf=0x3f3f3f3f;

const ll inf=long_long_max;

const int n=1e5+7;

int a[n];

int mx[n<<2];

void pushup(int rt)

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

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

build(rt<<1,l,mid);

build(rt<<1|1,mid+1,r);

pushup(rt);

}void modify(int rt,int l,int r,int x,int v)

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

if(x<=mid) modify(rt<<1,l,mid,x,v);

else modify(rt<<1|1,mid+1,r,x,v);

pushup(rt);

}int query(int rt,int l,int r,int l,int r,int v)

if(mx[rt]<=v) return -1;

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

int ans=-1;

if(l<=r&&l<=mid&&mx[rt<<1]>v)

ans=query(rt<<1,l,mid,l,r,v);

if(ans!=-1) return ans;

if(mid+1<=r&&l<=r&&mx[rt<<1|1]>v)

ans=query(rt<<1|1,mid+1,r,l,r,v);

if(ans!=-1) return ans;

return ans;

}int main()

else

} }return 0;

}

HDU6703 array(權值線段樹)

考慮建權值線段樹,那麼線段樹存的值就是它的座標,考慮到答案一定存在且最大值為n 1 n 1n 1,可以多加乙個點n 1 n 1n 1對於操作1 1,x 1,x 1,x 直接單點修改位置s x s x s x 為n 1 n 1n 1 s x 為初始位置x的值 對於操作2 2,r,x 2,r,x 2,r...

權值線緞樹

權值線緞樹就是特殊的線緞樹,他的結構和普通線緞樹一樣,每個結點都是表示一段區間的範圍 因此也需要開四倍空間 但是其每個結點儲存的是該區間的數出現的次數。權值線段樹維護的是桶 形象理解 1 快速計算一段區間的數的出現次數。2 快速找到第k大或第k小值。1 注意題目中資料範圍一般較大,數的值一般高達1e...

2019CCPC網路賽 array(權值線段樹)

題目位址 兩種操作 1.給 a i 10000000 2.查詢不存在 在a 1 r 中 且不低於k的數 在第乙個操作時 由於k的範圍不夠 就相當於把 a i 刪除掉即a i 的下標變為無窮大而對於第二種操作 也就是 等價為在 k之後 的下標的大於r 的可以使用權值線段樹用來維護當前區間最大的 下標如...