傳送門
首先考慮乙個貪心,我們把所有的人按\(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 他的狀態由他的子結點決定。...