洛谷P4559 JSOI2018 列隊(主席樹)

2022-02-27 12:37:53 字數 1297 閱讀 7576

傳送門

首先考慮乙個貪心,我們把所有的人按\(a_i\)排個序,那麼排序後的第乙個人到\(k\),第二個人到\(k+1\),...,第\(i\)個人到\(k+i-1\),易證這樣一定是最優的

然後發現這裡有乙個很重要的性質,\(a_i\)互不相同。那麼就必定存在乙個點\(mid\),在\(mid\)左邊(包括\(mid\))的空格子和人一樣多,右邊(不包括\(mid\))也一樣多

那麼很明顯,\(mid\)左邊的所有人都需要往右跑,\(mid\)右邊的所有人都需要往左跑

然後來康康答案啊……先看看\(mid\)左邊,第乙個人要跑\(k-a_1\),第二個人要跑\(k+1-a_2\),...,第\(mid-k+1\)個人要跑\(mid-a_\)……

這不就等價於\(\sum_^i-\sum_a_i\)嘛!

也就是說,左邊的答案就是\(k\)到\(mid\)的和,減去所有標號在\([l,r]\)區間內,且\(a_i\leq mid\)的\(a_i\)之和,一發主席樹就搞定了。右邊同理

順便這個\(mid\)也可以在主席樹上二分得到

//minamoto

#include#define r register

#define ll long long

#define fp(i,a,b) for(r int i=(a),i=(b)+1;ii;--i)

#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)

using namespace std;

char buf[1<<21],*p1=buf,*p2=buf;

inline char getc()

int read()

char sr[1<<21],z[20];int c=-1,z=0;

inline void ot()

void print(r ll x)

const int n=5e5+5,m=(n<<5);

ll sum[m],pre[n],ss,res;int sz[m],lc[m],rc[m],rt[n],a[n];

int n,m,l,r,k,cnt,zz,lim=2e6;

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

void update(int &p,int q,int l,int r,int x)

void query(int p,int q,int l,int r,int x)

int main()

return ot(),0;

}

洛谷P4049 JSOI2007 合金

某公司加工一種由鐵 鋁 錫組成的合金。他們的工作很簡單。首先進口一些鐵鋁錫合金原材料,不同種類的原材料中鐵鋁錫的比重不同。然後,將每種原材料取出一定量,經過融解 混合,得到新的合金。新的合金的鐵鋁錫比重為使用者所需要的比重。現在,使用者給出了 n 種他們需要的合金,以及每種合金中鐵鋁錫的比重。公司希...

洛谷P2018 訊息傳遞

巴蜀國的社會等級森嚴,除了國王之外,每個人均有且只有乙個直接上級,當然國王沒有上級。如果a是b的上級,b是c的上級,那麼a就是c的上級。絕對不會出現這樣的關係 a是b的上級,b也是a的上級。最開始的時刻是0,你要做的就是用1單位的時間把乙個訊息告訴某乙個人,讓他們自行散布訊息。在任意乙個時間單位中,...

洛谷P2018 訊息傳遞

由題意得這是一棵樹,而任何乙個已經接到訊息的人,都可以把訊息告訴他的乙個直接上級或者直接下屬,說明是一棵無根樹。本來以為要用什麼高階樹上演算法亂搞,結果發現 n leq 1000 這不是dfs就能水過嗎?實際上是個樹規 欽定乙個結點為根,我們在有根樹上做樹規。對於結點 x 他的狀態由他的子結點決定。...