hdu 3473 Minimum Sum 劃分樹的應用

來源:互聯網
上載者:User

標籤:劃分樹

連結:http://acm.hdu.edu.cn/showproblem.php?pid=3473


Minimum SumTime Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3427    Accepted Submission(s): 787


Problem DescriptionYou are given N positive integers, denoted as x0, x1 ... xN-1. Then give you some intervals [l, r]. For each interval, you need to find a number x to make as small as possible! 
InputThe first line is an integer T (T <= 10), indicating the number of test cases. For each test case, an integer N (1 <= N <= 100,000) comes first. Then comes N positive integers x (1 <= x <= 1,000, 000,000) in the next line. Finally, comes an integer Q (1 <= Q <= 100,000), indicting there are Q queries. Each query consists of two integers l, r (0 <= l <= r < N), meaning the interval you should deal with.

 
OutputFor the k-th test case, first output “Case #k:” in a separate line. Then output Q lines, each line is the minimum value of  . Output a blank line after every test case. 
Sample Input
253 6 2 2 421 40 227 720 11 1
 
Sample Output
Case #1:64Case #2:00
 

題意:

問l,r區間  取任意整數x ,  問 ∑|X-xi|  的最小值

做法:很明顯 這個X是中位元。 中位元想到劃分樹,然後在劃分樹 建樹的時候,把進左子樹的數計算一個首碼和,然後在查詢的時候,如果到右子樹,就把區間內進入左子樹的數算一個和。最後統計出來的sumlft 就是所有比區間內中位元小的數了。


//O(log(n)) 找第k大的值#include <iostream> #include <cstdio>#include <algorithm>using namespace std;#define N 100009#define M 19//M>log2,N;#define MID ((l+r)>>1)#define ll __int64int s[N];//s存的是 sort後的未經處理資料;int t[M][N];//t存的是樹;int numb[M][N];//和t數組同步,當前層,當前區間,N下標前有多少個數劃歸到左子樹.int n,m; ll quzuo[M][N];ll sum[N]; void Build(int c,int l,int r) //c是層數{int lm=MID-l+1,lp=l,rp=MID+1; //lp左邊的起點  rp 右邊的起點for(int i=l;i<=MID;i++)lm-=s[i]<s[MID]; //lm 代表 現在的左塊(下標l-MID)中 有多少等於s[MID]的 包括其本身int zuo,you;for(int i=l;i<=r;i++){zuo=you=0;if( i==l ){numb[c][i]=0; quzuo[c][i]=0;}else{numb[c][i]=numb[c][i-1];quzuo[c][i]=quzuo[c][i-1];}if(t[c][i]==s[MID]){if( lm )//左邊有多少等於中位元的的 都歸到左塊去{lm--;zuo=1;}else//如果 等於左塊的中位元用完了, 就放到右塊去 you=1; }else if( t[c][i]<s[MID] )//小的去左塊 zuo=1;  else you=1; if(zuo){  numb[c][i]++;t[c+1][lp++]=t[c][i];quzuo[c][i]+=t[c][i]; }else{  t[c+1][rp++]=t[c][i];}}if( l<r )Build(c+1,l,MID),Build(c+1,MID+1,r);}__int64 sumlft,sumrit;int numlft,numrit;int Query(int c,int l,int r,int ql,int qr,int k)//ql和qr是查詢的區間左右邊界,  l和r 當前區間.{if( l==r )return t[c][l];int s,ss;if( l==ql )s=0,ss=numb[c][qr];elses=numb[c][ql-1],ss=numb[c][qr]-numb[c][ql-1];if( k<=ss ){  return Query(c+1,l,MID,l+s,l+s+ss-1,k);}else{if(ql==l){ sumlft+=quzuo[c][qr]-0;}else{ sumlft+=quzuo[c][qr]-quzuo[c][ql-1];}return Query(c+1,MID+1,r,MID+1+ql-l-s,MID+1+qr-l-s-ss,k-ss);// ss到左子樹 所以ss在右子樹裡排名下降ss}} int main(){int tt;int cas=1;scanf("%d",&tt);while(tt--){scanf("%d",&n);sum[0]=0;for(int i=1;i<=n;i++){ s[i]=i;scanf("%d",&s[i]);t[0][i]=s[i];sum[i]=sum[i-1]+(ll)s[i];}sort(s+1,s+1+n);Build(0,1,n);scanf("%d",&m);printf("Case #%d:\n",cas++);while( m-- ){int l,r;sumlft=sumrit=numlft=numrit=0;//在進入右子樹的時候,把區間內 到左子樹的值加到sumlft中scanf("%d%d",&l,&r);// l-r 中 第k大,l從1開始 c=0開始,l++;r++;int ans;ans=Query(0,1,n,l,r,(r-l)/2+1);numlft=(r-l)/2;numrit=r-l-numlft;sumrit=sum[r]-sum[l-1]-sumlft-(ll)ans; //  printf("zuohe %d youhe %d  zuoshu %d youshu %d ans%d \n",sumlft,sumrit,numlft,numrit,ans);printf("%I64d\n",((ll)numlft*(ll)ans-sumlft)+(sumrit-(ll)numrit*(ll)ans));}puts("");}return 0;}



著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

hdu 3473 Minimum Sum 劃分樹的應用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.