hdu 划分树
来源:互联网 发布:unity3d shader 涂色 编辑:程序博客网 时间:2024/05/16 05:35
题意:给您一个数列 然后再给你一区间 让你在这个区间里找一个数使区间里的所有数与这个数差的绝对值和最小 ,
思路:
毫无疑问 这个数就是中位数(==可以推出来的) 对于区间是基数个 和偶数个 其实都一样 因为最后都约去了 : 假如x是所求的值 这个区间内比x小的有left个 比x大的有right个 其中left个的和为sum1 right个和位sum2 则所求为sum2-sum1 对于基数个与偶数个的问题只有left与right区别了 如果是奇数个则left==right 否则 left-right=1
这就好说了 如果不相等 也就是与最终结果差个x 。 其中sum1和left可以在查找的时候累加起来 这就就解决了!!!
#include<stdio.h>#include<iostream>#include<algorithm>#include<string.h>using namespace std;int num[100010],tree[20][100010],cont[20][100010];__int64 sum[20][100010],f[100010];int build(int floot,int L,int R){ int mid=(L+R)/2; int cc=mid-L+1; int lstar=L,rstar=mid+1,i; for(i=L;i<=mid;i++) { if(num[i]<num[mid]) cc--; } sum[floot][0]=0; for(i=L;i<=R;i++) { if(i==L) { cont[floot][i]=0; } else { cont[floot][i]=cont[floot][i-1]; } sum[floot][i]=sum[floot][i-1]; if(tree[floot][i]==num[mid]) { if(cc) { cc--; cont[floot][i]++; sum[floot][i]+=tree[floot][i]; tree[floot+1][lstar++]=tree[floot][i]; } else tree[floot+1][rstar++]=tree[floot][i]; } else if(tree[floot][i]<num[mid]) { cont[floot][i]++; sum[floot][i]+=tree[floot][i]; tree[floot+1][lstar++]=tree[floot][i]; } else { tree[floot+1][rstar++]=tree[floot][i]; } } if(L==R) return 0; build(floot+1,L,mid); build(floot+1,mid+1,R); return 0;}__int64 ss;int c;int find(int floot,int L,int R,int left,int right,int k){ if(L==R) return tree[floot][L]; int mid=(L+R)/2; int s1,s2; if(L==left) { s1=0; s2=cont[floot][right]; } else { s1=cont[floot][left-1]; s2=cont[floot][right]-s1; } if(k<=s2) { return find(floot+1,L,mid,L+s1,L+s1+s2-1,k); } else { c+=s2; ss+=sum[floot][right]-sum[floot][left-1]; return find(floot+1,mid+1,R,mid-L+1+left-s1,mid-L+1+right-s1-s2,k-s2); }}int main(){ int n,m,i,j,T,d=1; scanf("%d",&T); while(T--) { scanf("%d",&n); f[0]=0; for(i=1;i<=n;i++) { scanf("%d",&num[i]); tree[1][i]=num[i]; f[i]=f[i-1]+num[i]; } sort(num+1,num+1+n); build(1,1,n); int Q,left,right,k; scanf("%d",&Q); printf("Case #%d:\n",d++); while(Q--) { scanf("%d%d",&left,&right); left++; right++; ss=c=0; k=(right-left+2)/2; int t=find(1,1,n,left,right,k); __int64 x=f[right]-f[left-1]; int p=right-left+1; //printf("%I64d\n",(__int64)t*(c-(right-left+1-c))+f[right]-f[left-1]-ss-ss); printf("%I64d\n",(x-ss-ss)+((__int64)t*(2*c-p))); } printf("\n"); } return 0;}
0 0
- 【划分树】HDU 3473
- hdu 3473 划分树
- HDU 2665 划分树
- HDU 4251 划分树
- hdu 4251 划分树
- HDU 4251 划分树
- hdu 3473 划分树
- HDU 3727 划分树
- hdu 2665 划分树
- hdu 划分树
- hdu 2665 划分树
- hdu 2665 划分树
- hdu 2665 划分树
- hdu 4251 划分树
- hdu 3473 划分树
- hdu 4417 划分树
- HDU 3473 划分树
- hdu 3473(划分树)
- IE错误“Java(TM) 已被阻止,因为它已过时并且需要更新。”的解决方法
- 锐谷科技自助快递柜无线联网方案
- 二维码的生成细节和原理
- java第八章集合中的Collections操作集合的工具类
- ceph 认证高可用
- hdu 划分树
- ipv4\v6转换long型
- jdk环境变量配置
- (转)MySQL 查看约束,添加约束,删除约束 添加列,修改列,删除列(2011-10-27 13:38:48)
- nginx 禁止某个IP访问
- IPsec 和 NAT 的冲突问题详解
- 黑马程序员--接口、多态
- Linked List Cycle
- nginx 禁止某个IP访问站点