BZOJ2141 排隊(線段樹套Treap)

2022-05-14 14:36:11 字數 1746 閱讀 7107

點此看題面

大致題意:給你乙個序列,每次交換兩個數,求每次操作後的逆序對個數。

推薦先去看一下這道題目:【洛谷3759】[tjoi2017] 不勤勞的圖書管理員(貌似是此題的公升級版)。

推薦先去學一學線段樹套\(treap\)。(當然你也可以學習\(hl666\)奆佬分塊狂踩樹套樹)。

做了上面給出的那道題目,這道題目就是一道水題。

反正我是直接將上面那題**改了一下然後就過了。

關於具體實現可以見**。

#include#define max(x,y) ((x)>(y)?(x):(y))

#define min(x,y) ((x)<(y)?(x):(y))

#define uint unsigned ll

#define ll long long

#define ull unsigned long long

#define swap(x,y) (x^=y,y^=x,x^=y)

#define abs(x) ((x)<0?-(x):(x))

#define inf 1e9

#define inc(x,y) ((x+=(y))>=mod&&(x-=mod))

#define ten(x) (((x)<<3)+((x)<<1))

#define mod 1000000007

#define n 50000

#define logn 30

using namespace std;

int n,s[n+5];

class fio

else return (void)(void[++tot]=x,x=0);

}else node[x].val>val?del(node[x].son[0],val):del(node[x].son[1],val);

pushup(x);

}public:

class_treap()

inline void insert(int &rt,int val)

inline void delete(int &rt,int val)

inline int total_max(int rt,int val)

return res;

}inline int total_min(int rt,int val)

inline void upt(int l,int r,int rt,int pos,int val)

inline int total_max(int l,int r,int rt,int ql,int qr,int val)

inline int total_min(int l,int r,int rt,int ql,int qr,int val)

public:

inline void init(int len)

inline void insert(int pos,int val)

inline void update(int pos,int val)

inline int totalmax(int ql,int qr,int val)

inline int totalmin(int ql,int qr,int val)

}segmenttreap;

int main()

return f.end(),0;

}

bzoj 2141 排隊 樹套樹

交換位置l,r,對答案產生的影響是l,r內 比l大的數個數 比l小的數個數 比r小的數個數 比r大的數的個數 l和r交換後應該 1或 1 求這個東西用樹套樹就可以 做資料結構做傻了,還有很多其他優秀的做法 include include include define maxn 1700005 usi...

bzoj 2141 排隊 (樹狀陣列套線段樹)

題目大意 給出乙個序列,每次交換兩個位置的數,求交換完後整個序列的逆序對數。對於乙個位置會產生的逆序對數是他前面比他大的數 他後面比他小的數。我們可以用樹狀陣列套線段樹維護一下,外層表示位置在樹狀陣列中該點的控制區間,線段樹是權值線段樹。然後每次交換完了計算一下就可以了。include includ...

bzoj2141 排隊(線段樹 splay)

題目鏈結 分析 之所以找到這道題是因為不想寫dp了 看到網上的題解都是 分塊 線段樹,樹狀陣列 線段樹。立志自己想解法 一開始我在想,能不能用cdq搞 但是cdq版的動態逆序對好像是單點修改 實際上逆序對的個數就是每個數字形成的逆序對之和 而每個數會和在ta之前比ta大的數以及在ta之後比ta大的數...