码迷,mamicode.com
首页 > 其他好文 > 详细

hdu3473 线段树 划分树

时间:2014-09-29 23:44:21      阅读:305      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   ar   for   sp   

bubuko.com,布布扣
  1 //Accepted    28904 KB    781 ms
  2 //划分树
  3 //所求x即为l,r区间排序后的中位数t
  4 //然后求出小于t的数的和sum1,这个可以用划分树做
  5 //求出整个区间的和sum,可以用O(1)的数组做
  6 //ans=(k-1)*t-sum1+sum-sum1-(l-r+1-k+1)*t
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <iostream>
 10 #include <queue>
 11 #include <cmath>
 12 #include <algorithm>
 13 using namespace std;
 14 /**
 15   * This is a documentation comment block
 16   * 如果有一天你坚持不下去了,就想想你为什么走到这儿!
 17   * @authr songt
 18   */
 19 const int imax_n = 100005;
 20 struct node
 21 {
 22     int val[imax_n];
 23     int num[imax_n];
 24     __int64 sum[imax_n];
 25 }f[20];
 26 
 27 int a[imax_n];
 28 __int64 all[imax_n];
 29 int sorted[imax_n];
 30 int n;
 31 
 32 void build(int t,int l,int r)
 33 {
 34     if (l==r) return ;
 35     int mid=(l+r)/2;
 36     int isame=mid-l+1;
 37     int same=0;
 38     for (int i=l;i<=r;i++)
 39     {
 40         if (f[t].val[i]<sorted[mid]) isame--;
 41     }
 42     int ln=l;
 43     int rn=mid+1;
 44     for (int i=l;i<=r;i++)
 45     {
 46         if (i==l)
 47         {
 48             f[t].num[i]=0;
 49             f[t].sum[i]=0;
 50         }
 51         else
 52         {
 53             f[t].sum[i]=f[t].sum[i-1];
 54             f[t].num[i]=f[t].num[i-1];
 55         }
 56 
 57         if (f[t].val[i]<sorted[mid])
 58         {
 59             f[t].num[i]++;
 60             f[t].sum[i]+=f[t].val[i];
 61             f[t+1].val[ln++]=f[t].val[i];
 62         }
 63         else if (f[t].val[i]>sorted[mid])
 64         {
 65             f[t+1].val[rn++]=f[t].val[i];
 66         }
 67         else
 68         {
 69             if (same<isame)
 70             {
 71                 same++;
 72                 f[t].num[i]++;
 73                 f[t].sum[i]+=f[t].val[i];
 74                 f[t+1].val[ln++]=f[t].val[i];
 75             }
 76             else
 77             {
 78                 f[t+1].val[rn++]=f[t].val[i];
 79             }
 80         }
 81     }
 82     build(t+1,l,mid);
 83     build(t+1,mid+1,r);
 84 }
 85 __int64 sum=0;
 86 int lnum;
 87 int query(int t,int l,int r,int a,int b,int k)
 88 {
 89     int s,ss;
 90     if (l==r) return f[t].val[l];
 91     int mid=(l+r)/2;
 92     __int64 tsum=0;
 93     if (a==l)
 94     {
 95         ss=0;
 96         s=f[t].num[b];
 97         tsum=f[t].sum[b];
 98     }
 99     else
100     {
101         ss=f[t].num[a-1];
102         s=f[t].num[b]-ss;
103         tsum=f[t].sum[b]-f[t].sum[a-1];
104     }
105     if (s>=k)
106     {
107         a=l+ss;
108         b=l+ss+s-1;
109         return query(t+1,l,mid,a,b,k);
110     }
111     else
112     {
113         //lnum+=s;
114         int b1=a-l-ss;
115         int b2=b-a+1-s;
116         a=mid+1+b1;
117         b=mid+b1+b2;
118         sum+=tsum;
119         return query(t+1,mid+1,r,a,b,k-s);
120     }
121 }
122 int Q;
123 int x,y;
124 void slove()
125 {
126     build(0,1,n);
127     scanf("%d",&Q);
128     for (int i=1;i<=Q;i++)
129     {
130         scanf("%d%d",&x,&y);
131         x++;
132         y++;
133         __int64 sum1=all[y]-all[x-1];
134         //printf("sum1=%I64d\n",sum1);
135         sum=0;
136         //lnum=0;
137         //printf("sum=%I64d\n",sum);
138         int k=(x+y)/2-x+1;
139         int t=query(0,1,n,x,y,k);
140         //printf("t=%d\n",t);
141         lnum=k-1;
142         __int64 ans=-sum+sum1-sum-(__int64 )(y-x+1-lnum-lnum)*t;
143         printf("%I64d\n",ans);
144     }
145 }
146 int main()
147 {
148     int T;
149     int t=0;
150     scanf("%d",&T);
151     while (T--)
152     {
153         scanf("%d",&n);
154         all[0]=0;
155         for (int i=1;i<=n;i++)
156         {
157             scanf("%d",&a[i]);
158             f[0].val[i]=sorted[i]=a[i];
159             all[i]=all[i-1]+a[i];
160         }
161         printf("Case #%d:\n",++t);
162         sort(sorted+1,sorted+n+1);
163         slove();
164         printf("\n");
165     }
166     return 0;
167 }
View Code

 

hdu3473 线段树 划分树

标签:style   blog   http   color   io   os   ar   for   sp   

原文地址:http://www.cnblogs.com/djingjing/p/4000934.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!