將所有區間按li-ri排序,那麼答案一定是一段連續的區間
有單調性,兩個指標掃
一段區間是合法的當且僅當這個區間中存在乙個點被超過m個區間覆蓋
線段樹維護區間最大值,支援區間加法操作即可
notice:l,r達到了1e9,需要離散化
/**
****
****
****
****
****
****
****
****
****
****
****
****
****
****
****
problem: 4653
user: di4covery
language: c++
result: accepted
time:9464 ms
memory:67700 kb
****
****
****
****
****
****
****
****
****
****
****
****
****
****
****
****/
#include
#include
#include
#define n 1000050
#define mid ( (l + r) >> 1 )
#define ls l,mid,t<<1
#define rs mid+1,r,t<<1^1
using namespace std;
struct monsterq[n];
bool operator <(monster p1,monster p2)
inttr[4
*n],ag[4
*n];
int d[2
*n],e[2
*n],a[2
*n];
int ll,rr,v,tp,ans,n,m;
bool cmp(int p1,int p2)
inline void ut(int &x,int
y) void push_down(int t)
void update(int l,int r,int t )
push_down(t); update(ls); update(rs);
tr[t] = max(tr[t<<1],tr[t<<1^1]);
}int main()
//àë颻¯
for (int i=1;i<=2
*n;i++) e[i] = i;
sort(e+1,e+2
*n+1,cmp);
for (int i=1;i<=2
*n;i++)
a[ e[i] ] = d[ e[i] ] == d[ e[i-1] ] ? a[ e[i-1] ] : a[ e[i-1] ] + 1;
for (int i=1;i<=n;i++) q[i].l = a[2
*i-1] , q[i].r = a[2
*i];
tp = a[ e[2
*n] ];
sort(q+1,q+n+1);
int h = 1 , t = 0;
while (tr[1] < m && t < n)
ans = 1
<<30;
if (tr[1] >= m) ut(ans, q[t].w-q[1].w );
while (t < n)
if (tr[1] >= m) ut(ans , q[t].w-q[h].w);
}if (ans == (1
<<30)) ans = -1;
printf("%d\n",ans);
return
0;}
bzoj 4650 Noi2016 優秀的拆分
原來只會兩個log平衡樹合併。後來圍觀claris在uoj群上秒題後會了這道題。列舉a b 的長度l,然後列舉i kl,考慮字首i,i l和字尾i 1,i l 1,求出字首的lcp和字尾的lcp,然後合法的方案就在乙個方案內。差分一下即可。注意要避免重複。ac 如下 include include ...
BZOJ4560 NOI2016 優秀的拆分
bzoj 洛谷考慮乙個形如 aabb 的串是由兩個形如 aa 的串拼起來的 那麼我們設 f i 以位置 i 為結尾的形如 aa 串的個數 g i 以位置 i 為開頭的形如 aa 串的個數 therefore ans sum nf i g i 1 題目的難點轉化為求 f,g 但是,其實我們只要 o n...
BZOJ 4650 Noi2016 優秀的拆分
題解 求解每個位置向左向右aa串的個數f x g x 列舉a的長度,每a個位置設乙個關鍵點 每乙個a一定僅且跨越乙個關鍵點 然後求出相鄰關鍵點向前向後的最長公共字首的長度,這會對一段區間的f,g產生影響 用差分 字首和統計答案 include include include includeusing...