zoukankan      html  css  js  c++  java
  • HDU 3473 Minimum Sum(划分树)

    Minimum Sum

    Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 2235    Accepted Submission(s): 512


    Problem Description
    You 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!
     
    Input
    The 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.

     
    Output
    For 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
    2 5 3 6 2 2 4 2 1 4 0 2 2 7 7 2 0 1 1 1
     
    Sample Output
    Case #1: 6 4 Case #2: 0 0
     
    Author
    standy
     
    Source
     
    Recommend
    zhengfeng
     

    其实就是找到中间那个数。

    然后需要记录和,右边的减掉左边的

    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    #include <string.h>
    using namespace std;
    const int MAXN = 100010;
    int tree[20][MAXN];
    int sorted[MAXN];
    int toleft[20][MAXN];
    long long sum[20][MAXN];
    
    void build(int l,int r,int dep)
    {
        if(l == r)
        {
            sum[dep][l] = sum[dep][l-1]+tree[dep][l];
            return;
        }
        int mid = (l+r)>>1;
        int same = mid - l + 1;
        for(int i = l;i <= r;i++)
        {
            if(tree[dep][i] < sorted[mid])
                same--;
            sum[dep][i] += sum[dep][i-1]+tree[dep][i];
        }
        int lpos = l;
        int rpos = mid+1;
        for(int i = l;i <= r;i++)
        {
            if(tree[dep][i] < sorted[mid])
                tree[dep+1][lpos++] = tree[dep][i];
            else if(tree[dep][i] == sorted[mid] && same > 0)
            {
                tree[dep+1][lpos++] = tree[dep][i];
                same--;
            }
            else
                tree[dep+1][rpos++] = tree[dep][i];
            toleft[dep][i] = toleft[dep][l-1] + lpos - l;
        }
        build(l,mid,dep+1);
        build(mid+1,r,dep+1);
    }
    long long ans;
    int query(int L,int R,int l,int r,int dep,int k)
    {
        if(l == r)return tree[dep][l];
        int mid = (L+R)>>1;
        int cnt = toleft[dep][r] - toleft[dep][l-1];
        if(cnt >= k)
        {
            int ee = r-L+1-(toleft[dep][r]-toleft[dep][L-1])+mid;
            int ss = l-L-(toleft[dep][l-1]-toleft[dep][L-1])+mid;
    
            ans += sum[dep+1][ee]-sum[dep+1][ss];
    
            int newl = L + toleft[dep][l-1]-toleft[dep][L-1];
            int newr = newl + cnt -1;
            return query(L,mid,newl,newr,dep+1,k);
        }
        else
        {
            int s = L + toleft[dep][l-1] - toleft[dep][L-1];
            int e = s + cnt - 1;
    
            ans -= sum[dep+1][e] - sum[dep+1][s-1];
    
            int newr = r + toleft[dep][R] - toleft[dep][r];
            int newl = newr - (r-l+1-cnt) + 1;
            return query(mid+1,R,newl,newr,dep+1,k-cnt);
        }
    }
    int main()
    {
        int T;
        int n;
        scanf("%d",&T);
        int iCase = 0;
        while(T--)
        {
            iCase++;
            scanf("%d",&n);
            memset(tree,0,sizeof(tree));
            memset(sum,0,sizeof(sum));
            for(int i = 1;i <= n;i++)
            {
                scanf("%d",&tree[0][i]);
                sorted[i] = tree[0][i];
            }
            sort(sorted+1,sorted+n+1);
            build(1,n,0);
            printf("Case #%d:
    ",iCase);
            int m,l,r;
            scanf("%d",&m);
            while(m--)
            {
                scanf("%d%d",&l,&r);
                l++;r++;
                ans = 0;
                int tmp = query(1,n,l,r,0,(l+r)/2-l+1);
                if((l+r)%2)ans-=tmp;
                printf("%I64d
    ",ans);
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    map函数
    修改文件夹所有者权限
    [Python]Python基础趣讲精练
    jmeter生成随机字符串
    Jmeter生成8位不重复的随机数
    Jmeter接口测试使用总结
    Jmeter模拟多个号码注册
    Jmeter实现多用户注册登录
    jmeter 生成随机数(手机号)&随机中文字符
    python接口自动化如何封装获取常量的类
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3224432.html
Copyright © 2011-2022 走看看