從左到右枚舉優美區間的右端點,假設當前枚舉到,那麼區間爲優美區間當且僅當
其中爲中相差爲的數對的數對個數
枚舉到時我們將與的貢獻計入
設所在位置爲,所在位置爲
那麼若且時會對產生的貢獻
所以我們只需一棵茲磁區間加法與區間求最大值的線段樹即可
我們用堆按從大到小維護,對於詢問,我們在線段樹上查詢的的最大值以及最大的,若則找到了該詢問的答案,將該詢問從堆中彈出,否則將其留在堆中,並枚舉下一個
顯然若存在優美區間與滿足且互不包含,那麼區間也是優美的,因此可以保證這樣最優
Code
區間詢問的第二種寫法比第一種寫法不知快到哪裏去了
Pair ask(LL l,LL r,LL now,LL x,LL y){
if (x<=l && r<=y) return tr[now];
if (r<x || l>y) return Pair(0,0);
pd(now);
return max(ask(l,mid,lson,x,y),ask(mid+1,r,rson,x,y));
}
Pair ask(LL l,LL r,LL now,LL x,LL y){
if (x<=l && r<=y) return tr[now];
if (r<x || l>y) return Pair(0,0);
pd(now);
Pair res=Pair(0,0);
if (mid>=x) cmax(res,ask(l,mid,lson,x,y));
if (mid+1<=y) cmax(res,ask(mid+1,r,rson,x,y));
return res;
}