題目:z
yb
有乙個排列pp
,但他只記得pp
中每個字首區間的逆序對數,現在他要求你還原這個排列.
輸入:1
3 0 1 2
輸出:3 1 2
題解:num[k]-num[k-1] 是排列中第k個數貢獻的逆序數對,故 k-(num[k]-num[k-1])是第k個數在前k個數中的排名(從小到大)。
逆向確認排列,確認第n個數後,刪除這個數的值。
再確認第n-1個數,它在剩下的數中排名 n-1-(num[n-1]-num[n-2])。依此類推。
很容易用
線段樹維護區間剩下數的個數,進而求得第k大。#include #include #include #include #include using namespace std;
const int maxn=200005;
const int inf=1000000007;
struct nodenode[maxn<<2];
int num[maxn];
int ans[maxn];
void build(int i,int l,int r)
int mid=l+((r-l)>>1);
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
node[i].value=node[i<<1].value+node[i<<1|1].value;
}int query(int i,int key)
//這裡的更新相當於刪除確定的數
void update_line(int i,int l,int r,int change)
int p1,p2;
int mid=(node[i].left+node[i].right)>>1;
if(l>mid)
update_line(i<<1|1,l,r,change);
else if(r<(mid+1))
update_line(i<<1,l,r,change);
else
node[i].value=node[i<<1].value+node[i<<1|1].value;
}int main()
num[0]=0;
for(int i=n;i>=1;i--)
for(int i=1;i
hdu 1754 區間最大線段樹基礎題)
include define m 200005 define lson l,m,rt 1 define rson m 1,r,rt 1 1 int max m 2 void pushdata int rt void bulid int l,int r,int rt int m l r 1 bulid...
HDU 5592ZYB 線段樹求第K大
hdu 5592zyb 線段樹求第k大 題意 給出你每插入乙個數,逆序數的總數。問原序列?題解 解釋樣例 0 1 2當第乙個位置插入乙個數時,逆序數的為0。二。1.三。2.從後往前推,當第三個數插入後,個數由1變成2個,說明前面有乙個大於他的數,既他是序列中第二大的,就是2.其他自己推。建一棵線段樹...
HDU 5700 區間交(線段樹)
problem description 小a有乙個含有n個非負整數的數列與m個區間。每個區間可以表示為li,ri。它想選擇其中k個區間,使得這些區間的交的那些位置所對應的數的和最大。例如樣例中,選擇 2,5 與 4,5 兩個區間就可以啦。input 多組測試資料 第一行三個數n,k,m 1 n 10...