題意:給出乙個長度為n的序列,每次將某個子串行分成兩段,輸出所有段中逆序對最大的數目。
題解:假設從x位置斷開,找到x最左邊的斷點l,和最右邊的斷點r,那麼就是把區間(l,r)分解為(l,x)和(x,r),如何維護兩段的逆序對個數呢?
啟發式分解
假設斷點更靠近r,我們暴力求解出(x,r)的逆序對個數,再求解出(l,x)和(x,r)中兩段各有乙個數的逆序對的個數,也就是有交叉的逆序對個數,再讓(l,r)中的逆序對個數減去那兩項就是(l,x)的逆序對個數。
暴力求解的方法:
將區間(x,r)中的元素建立名次樹,每加入乙個元素之前看樹中大於它的個數,累加就是(x,r)的逆序對個數。
(l,x)是一顆名次樹,列舉(x,r)中的元素,看在(l,x)中大於它的個數,累加有交叉的逆序對個數。
進而求得(l,x)的逆序對個數。
假設斷點更靠近l,方法基本和上面的一樣,不過需要乙個交換樹的操作,原因請自己思考。
用的函式是pb_ds中rb_tree中的order_of_key
注意由於rb_tree中不能有重複元素,需要用結構體,然後過載大於號
#include#include#define n 100010
#define inf 0x3f3f3f3f
#define eps 1e-10
#define pi 3.141592653589793
#define ll long long
#define pb push_back
#define cl clear
#define si size
#define lb lower_bound
#define ook order_of_key
#define mem(x) memset(x,0,sizeof x)
#define sc(x) scanf("%d",&x)
#define scc(x,y) scanf("%d%d",&x,&y)
#define sccc(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;
#include#includeusing namespace __gnu_pbds;
struct node
bool operator >(node b) const
};tree,rb_tree_tag,tree_order_statistics_node_update> t[n];
int a[n];
setst; mapmp; multiseta;
int f[n];
int main()
mp[0]=ans; a.insert(ans);
for (int i=1;i<=n;i++)
f[0]=0;
ll ans=0; st.clear(); mp.clear(); a.clear();
st.insert(0); st.insert(n+1);
for (int i=1;i<=n;i++)
mp[0]=ans; a.insert(ans);
for (int i=1;i<=n;i++)
{auto p=a.end(); p--; ans=*p;
printf("%lld",ans); if (i
2018 icpc 南京網路賽
題目 鏈結 a.an olympian math problem 輸出n 1即可 女朋友猜的 includeusing namespace std define ll long long ll fac 103 int main for int i 1 i m i ll ans 0 for int i...
2018 ICPC 南京網路賽 skr
題意 給出乙個字串,求它的所有回文子串轉化成數字的和,對1e9 7取模。題解 先上manacher,然後列舉每個點,按照半徑從大到小的順序列舉回文串,遇到出現過的就break,統計答案即可。注意的是,判重時只能用pb ds中的gp hash table,unordered map會t,同時需要兩個字...
2018ICPC北京賽總結
00 05.23 冰冷而空曠啊,00 11.83 燈火離我遠去,00 18.95 誰知你何時會犧牲 00 33.17 永別了,親愛的故土!00 39.61 這離別真切得讓我不能相信。00 46.63 母親啊,故鄉啊,00 53.45 永別了,偉大的祖國!01 04.11 讓我們起航吧,大海在召喚我們...