首先交換的兩個數兩邊的數產生的逆序對數不變。
那麼只需要考慮中間的數和兩個數本身。
只考慮第乙個數大於第二個數的情況(小於的情況是這個的逆過程)
首先答案-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...