bzoj 2141 線段樹套權值線段樹

2021-07-23 20:07:05 字數 1021 閱讀 6409

首先交換的兩個數兩邊的數產生的逆序對數不變。

那麼只需要考慮中間的數和兩個數本身。

只考慮第乙個數大於第二個數的情況(小於的情況是這個的逆過程)

首先答案-1(這兩個數產生的逆序對)

答案-位置在兩個數之間並且值也在兩個數之間的數的個數×2

答案-位置在兩個數之間並且值與兩個數中的乙個相等的數的個數

可以用樹套樹維護這個東西。

#include 

using

namespace

std;

#define n 21000

#define m 11000000

#define a 1000000010

#define ll long long

int n,m,cnt,l1,r1,l2,r2;

int a[n];

int ch[m][2],val[m],root[n<<2];

ll ans;

struct val_tree

int query(int l,int r,int x)

}tr2;

struct pos_tree

int query(int l,int r,int now)

}tr1;

int main()

printf("%lld\n",ans);

scanf("%d",&m);

for(int x,y;m--;)

l1=x+1;r1=y-1;

if(a[x]>a[y])

else

tr1.insert(1,n,1,x,a[x],-1);

tr1.insert(1,n,1,y,a[y],-1);

swap(a[x],a[y]);

tr1.insert(1,n,1,x,a[x],1);

tr1.insert(1,n,1,y,a[y],1);

printf("%lld\n",ans);

}return

0;}

BZOJ2141 排隊(線段樹套Treap)

點此看題面 大致題意 給你乙個序列,每次交換兩個數,求每次操作後的逆序對個數。推薦先去看一下這道題目 洛谷3759 tjoi2017 不勤勞的圖書管理員 貌似是此題的公升級版 推薦先去學一學線段樹套 treap 當然你也可以學習 hl666 奆佬分塊狂踩樹套樹 做了上面給出的那道題目,這道題目就是一...

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

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

bzoj 2141 排隊 樹套樹

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