hdu 3473 Minimum Sum
2012-12-09 15:48
267 查看
题意:给出n个数x1,x2...xn.进行m次操作,每次给出一个区间[l ,r].求出xi属于区间[l, r]使得该区间的每个数与xi的差之和最小,并求出该和。
思路:划分树。
View Code
思路:划分树。
View Code
#include <cstdio> #include <algorithm> using namespace std; #define lson l,m,rt+1 #define rson m+1,r,rt+1 #define maxn 100001 struct node { int val[maxn]; int num[maxn]; __int64 sum[maxn]; }setree[18]; int sorted[maxn]; __int64 ans[maxn],sum; void build(int l,int r,int rt) { if(l==r) return ; int m=(l+r)>>1; int isame=m-l+1,same=0; int ln=l,rn=m+1; for(int i=l;i<=r;i++) if(setree[rt].val[i]<sorted[m]) isame--; for(int i=l;i<=r;i++){ if(i==l){ setree[rt].num[i]=0; setree[rt].sum[i]=0; } else{ setree[rt].num[i]=setree[rt].num[i-1]; setree[rt].sum[i]=setree[rt].sum[i-1]; } if(setree[rt].val[i]<sorted[m]){ setree[rt].num[i]++; setree[rt].sum[i]+=setree[rt].val[i]; setree[rt+1].val[ln++]=setree[rt].val[i]; } else if(setree[rt].val[i]>sorted[m]) setree[rt+1].val[rn++]=setree[rt].val[i]; else{ if(same<isame){ same++; setree[rt].num[i]++; setree[rt].sum[i]+=setree[rt].val[i]; setree[rt+1].val[ln++]=setree[rt].val[i]; } else setree[rt+1].val[rn++]=setree[rt].val[i]; } } build(lson); build(rson); } __int64 query(int l,int r,int rt,int L,int R,int k) { if(L==R) return setree[rt].val[L]; int m=(l+r)>>1; int enterleft1,enterleft2,enterright1,enterright2; __int64 ss; if(L==l){ enterleft1=0; enterleft2=setree[rt].num[R]; enterright1=0; enterright2=R-l+1-setree[rt].num[R]; ss=setree[rt].sum[R]; } else{ enterleft1=setree[rt].num[L-1]; enterleft2=setree[rt].num[R]; enterright1=L-l-setree[rt].num[L-1]; enterright2=R-l+1-setree[rt].num[R]; ss=setree[rt].sum[R]-setree[rt].sum[L-1]; } int temp=enterleft2-enterleft1; if(temp>=k) return query(lson,l+enterleft1,l+enterleft2-1,k); else{ sum+=ss; return query(rson,m+enterright1+1,m+enterright2,k-temp); } } int main() { int t; scanf("%d",&t); int cas=1; while(t--){ int n,m; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&setree[0].val[i]); sorted[i]=setree[0].val[i]; if(i==0) ans[i]=setree[0].val[i]; else ans[i]=ans[i-1]+setree[0].val[i]; } sort(sorted,sorted+n); build(0,n-1,0); scanf("%d",&m); printf("Case #%d:\n",cas++); while(m--){ int l,r,k; scanf("%d%d",&l,&r); k=(r-l+2)/2; sum=0; __int64 temp=query(0,n-1,0,l,r,k); __int64 sum1=ans[r]-ans[l-1]-sum; printf("%I64d\n",sum1-sum-(r-l+2-k)*temp+(k-1)*temp); } printf("\n"); } return 0; }
相关文章推荐
- hdu 3473 Minimum Sum 划分树的应用
- HDU 3473 Minimum Sum 划分树
- hdu 3473 Minimum Sum(划分树)
- hdu 3473 Minimum Sum
- hdu 3473 Minimum Sum(划分树-sum操作)
- HDU 3473 Minimum Sum 划分树
- Minimum Sum - HDU 3473 划分树
- hdu 3473 Minimum Sum(划分树)
- hdu 3473 Minimum Sum 再来一波划分树,对划分树累觉不爱。
- hdu 3473 Minimum Sum
- HDU 3473 Minimum Sum 划分树
- HDU 3473-Minimum Sum(划分树-求区间sigma最小值)
- hdu 3473 Minimum Sum
- HDU 3473 Minimum Sum (划分树)
- hdu 3473 Minimum Sum 划分树
- HDU 3473 Minimum Sum 划分树
- HDU 3473 Minimum Sum【划分树】
- HDU 3473 Minimum Sum
- HDU 3473 Minimum Sum 划分树
- hdu 3473 Minimum Sum