日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CodeForces - 1452E Two Editorials(二阶差分)

發布時間:2024/4/11 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces - 1452E Two Editorials(二阶差分) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出 m 個區間,現在可以選擇兩段長度為 k 的區間進行覆蓋,記為 a 和 b,對于每個區間來說,假設被 a 覆蓋的長度為 len_a,被 b 覆蓋的長度為 len_b,假設 len_a > len_b,那么其將會被 a 覆蓋,且提供 len_a 的貢獻,反之被 b 覆蓋且提供 len_b 的貢獻,問如何選擇 a 和 b 可以使得總貢獻最大

題目分析:比較顯然的一個 n^3 的暴力就是:O( n ) 枚舉 a,O( n ) 枚舉 b,最后 O( n ) 枚舉每個區間計算貢獻

考慮優化,假設我們已經枚舉好了 a,記為 [ L , R ],再計算每個區間與其交集,len[ i ] 表示的是第 i 個區間與 [ L , R ] 的交集,不過此時我們默認的是所有 len[ i ] > 0 的區間都是被 a 覆蓋的,所以我們考慮差分維護一下貢獻,我們最后的目標是為了得到一個數組 len_b,len_b[ i ] 代表的是,如果 b 的左端點或右端點選擇到了點 i 時,不與 a 的覆蓋所沖突的最大貢獻,這句話可以這樣理解:依然假設 len_a 和 len_b 是與某段區間交集的長度,顯然?len_a?就是剛剛求出的 len[ i ]?了:

  • 如果 len_a >= len_b:那么此時該區間選擇被 a 覆蓋是更優的,所以?b 不做貢獻
  • 如果 len_a < len_b:那么此時被區間 b 覆蓋是更優的,且被 b 覆蓋后,貢獻增加了 len_b - len_a
  • 所以我們的目標就是維護出 len_b[ i ] 這個數組即可

    畫兩張圖應該就可以包含所有情況了

    我們這里的 len_b[ i ] 代表的是,b 的右端點取到點 i 時的?貢獻差

    不難看出上述兩個圖中,當點 i 取到綠色區域時,隨著 i 右移,貢獻會不斷加一,當點 i 取到黃色區域時,貢獻會不變,當點 i 取到藍色區域時,會隨著 i 右移貢獻不斷減一,這個自己想一下應該就能想過來了

    所以對 len_b[ i ] 初始時維護一個二階差分,然后兩次前綴和復原即可,上面的幾個關鍵位置都特地寫出來了,直接實現即可

    代碼:
    ?

    //#pragma GCC optimize(2) //#pragma GCC optimize("Ofast","inline","-ffast-math") //#pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e3+100;int l[N],r[N],delta[N<<1];int cal(int l1,int r1,int l2,int r2)//計算交集長度 {return max(0,min(r1,r2)-max(l1,l2)+1); }int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int n,m,k;scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=m;i++)scanf("%d%d",l+i,r+i);int ans=0;for(int i=1;i+k-1<=n;i++){int L=i,R=i+k-1;int res=0;memset(delta,0,sizeof(delta));for(int i=1;i<=m;i++){int len=cal(l[i],r[i],L,R);res+=len;delta[l[i]+len]++;delta[min(r[i]+1,l[i]+k)]--;delta[max(r[i]+1,l[i]+k)]--;delta[r[i]+k-len+1]++;}for(int i=1;i<=n;i++)//還原二階差分 delta[i]+=delta[i-1];for(int i=1;i<=n;i++)//還原一階差分 delta[i]+=delta[i-1];for(int i=1;i<=n;i++)ans=max(ans,delta[i]+res);}printf("%d\n",ans);return 0; }

    ?

    總結

    以上是生活随笔為你收集整理的CodeForces - 1452E Two Editorials(二阶差分)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。