Luogu P1975 國家集訓隊 排隊

2022-09-21 12:09:12 字數 1277 閱讀 1138

luogu 1975 [國家集訓隊]排隊

\(\quad\)很明顯交換後能增加或減少的逆序對的個數只和這兩個數和這兩個數中間的數有關。

\(\quad\)於是我們需要乙個資料結構能夠快速求出乙個區間內比乙個特定數值大、小的個數。

\(\quad\)這個資料結構可以是分塊,這在分塊九講裡面有提到過,這裡就不再闡述具體操作過程了。

\(\quad\)至於交換操作肯定不可能將整個快重新排序,只用將新插入的值找好自己相對的位置就行了。

#include#define ll long long

#define double

#define fo(i,j,k) for(register int i=j;i<=k;++i)

#define fd(i,j,k) for(register int i=j;i>=k;--i)

#define ff(i,x) for(register int i=head[x];i;i=e[i].nxt)

#define fv(i,x) for(register int i=0;i'9')

while(ch>='0' && ch<='9')

return f?-ret:ret;

}int a[n],b[n],p[n],ov[n],ans,bl[n],sq,pa[n],tag[n],up[n],n,m,l[n],r[n];

inline void mergesort(int l,int r)

else

}else

fo(i,l[bl[v]],v-1)

fo(i,bl[u]+1,bl[v]-1)

if(ov[l[i]]a[v])

}int l=l[bl[u]],r=r[bl[u]],c=a[u];

int tmp=lower_bound(ov+l,ov+r+1,c)-ov;

ov[tmp]=a[v];

while(tmp>l && ov[tmp]ov[tmp+1]) swap(ov[tmp],ov[tmp+1]),++tmp;

l=l[bl[v]],r=r[bl[v]],c=a[v];

tmp=lower_bound(ov+l,ov+r+1,c)-ov;

ov[tmp]=a[u];

while(tmp>l && ov[tmp]ov[tmp+1]) swap(ov[tmp],ov[tmp+1]),++tmp;

}swap(a[u],a[v]);

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

}} return 0;

}

Luogu 1975 國家集訓隊 排隊

luogu 1975 題意 給出乙個長度為n的數列以及m個交換兩個數的操作,問每次操作後逆序對數量 時間,下標和數的大小三維偏序,把交換操作看成是減去兩個數再加上兩個數,套板子就好了 發現這種計數型別的cdq一般有兩種寫法 感覺應該都差不多,但有些題目用兩種方式寫也有一些優劣之分,比如這道題,用第二...

luogu P1505 國家集訓隊 旅遊

題面傳送門 第一次一遍過國集紫題。好激動。一看就是樹剖,只不過操作有點多。把每條邊的權值放在兒子節點即可。對於取相反數放懶標記即可。其他是樹剖正常操作。實現 include include define max a,b a b a b define min a,b a b a b using nam...

Luogu P2839 國家集訓隊 middle

首先 b,c 是必選的,然後選一段 a,b 的字尾和一段 c,d 的字首 都可空 對於中位數 這裡中位數採用這道題的定義 有個常見的處理方式 二分 mid,將 0,則說明 mid 的佔到了一半以上,即中位數 mid。採用這種處理方式,二分中位數,由於要中位數盡量大,所以要貪心,選字尾和字首使得大於等...