2018牛客多校第五場 H subseq

2021-08-22 09:54:22 字數 1376 閱讀 5677

傳送門:

這場樹狀陣列用法專場,skydec說這題很套路的題,很簡單,然而處理處dp陣列後最後的貪心我想了半天還問了一蛤別人,菜不成聲.jpg,先處理出dp陣列,dp[i]表示以a[i]為開頭的從i到n的所有遞增子串行的方案數,本來應該用線段樹了,然而好多人使用了神奇的樹狀陣列,以前都是add函式從i到cnt,sum函式從i到0,但這裡的方案數是會超過1e18的,那麼樹狀陣列中的值大於1e18的時候立刻賦值為1e18,那麼如果還是sum從i到0的話,這裡在計算dp[i]的時候dp[i]=sum(cnt)-sum(a[i]+1),因為大於1e18賦值的時候是會出錯的,所以這裡的add函式變成從i到0,sum函式變成從i到cnt,這樣的樹狀陣列竟然也可以!漲見識了

預處理出dp[i]接下來就是貪心求第k大的方案了,從i=1-->n按位考慮,如果當前剩餘k<=dp[i],那麼a[i]必須是答案中的,因為如果第i位不選,那麼以a[i]為開頭的子串行個數將大於等於k,所以a[i]必定是大小等於k的子串行中的乙個元素,此時總第k大序列少了a[i]這乙個單元素序列,k--,而如果k>dp[i],則如果在答案中加入a[i],再去後面找遞增序列,怎麼找也找不到第k大,所以a[i]不可能在答案序列中,而且此時以a[i]為開頭的所有遞增子串行再加上前面已加入答案的子串行字典序一定是要比答案小的,所以此時k-=dp[i],這個地方我想了很久沒想清楚,問了一波tsz,假設當前答案中已經加入了1,2 兩個元素,此時3號元素dp[i]要比k大,我們考慮dp[i]的問題,他是從後往前推出的陣列,如果3號元素要比1號元素大,那麼k在1號元素的地方就已經把3號元素考慮過了,因為dp[1]的方案數是包括dp[3]的,此時把這一位後面的所有情況都加上,還是達不到k,那麼字典序就全比k小,如果3號元素比1號元素小,那就沒什麼問題了。

#include#include#include#define maxl 500010

using namespace std;

const long long inf=1e18+1;

int n,cnt;

int a[maxl];

struct node

s[maxl];

long long k;

long long b[maxl],dp[maxl];

int ans[maxl];

inline bool cmp(const node &x,const node &y)

}inline long long sum(int i)

return s;

}inline void mainwork()

ans[0]=0;

for(int i=1;i<=n;i++) }

}inline void print()

}int main()

return 0;

}

牛客 2018多校演算法第五場C KMP

字串的問題 在原來的字串中字首與字尾相同,且原來的中間還含有這個子串 這裡加的num 陣列真是太厲害了,可以直接用來判斷中間是否有子串 include include include include include using namespace std const int maxn 1e6 7 i...

牛客多校(第五場)E room

將乙個房間當做乙個點,後來的房間與之前的房間中不用搬的人作為權值,建圖,跑最大權匹配,就是不用搬的人數,在減一下即可,km演算法,o n 3 include include include includeusing namespace std define n 200 define inf 0x3f...

2019 8 1 牛客多校第五場

index 牛客多校第五場 題號標題 通過率做法狀態a digits 2 1017 2383 簽到 bgenerator 1 555 3660 矩陣快速冪 十進位制優化 cgenerator 2 37 626 dgenerator 3 4 23 eindependent set 1 45 110 f...