點此看題面
大致題意:給你乙個序列,每次交換兩個數,求每次操作後的逆序對個數。
推薦先去看一下這道題目:【洛谷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大的數...