华中农业大学第四届程序设计大赛网络同步赛 G.Array C 线段树或者优先队列

Problem G: Array C

Time Limit: 1 Sec  Memory Limit: 128 MB

Description

   Giving two integers  and  and two arrays  and  both with length , you should construct an array  also with length  which satisfied:

1.0≤CiAi(1≤in)

2.

and make the value S be minimum. The value S is defined as:

Input

   There are multiple test cases. In each test case, the first line contains two integers n(1≤n≤1000) andm(1≤m≤100000). Then two lines followed, each line contains n integers separated by spaces, indicating the array Aand B in order. You can assume that 1≤Ai≤100 and 1≤Bi≤10000 for each i from 1 to n, and there must be at least one solution for array C. The input will end by EOF.

Output

    For each test case, output the minimum value S as the answer in one line.

Sample Input

3 4 
2 3 4
1 1 1

Sample Output

6
思路:首先我们会想找到最小的一直下去,但是有个A数组为上界不好处理,所以先将C数组全部修改成A数组,一直向下减,当C相加等于M的时候得到答案;
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
#define inf 999999999
#define esp 0.00000000001
//#pragma comment(linker, "/STACK:102400000,102400000")
int scan()
{
    int res = 0 , ch ;
    while( !( ( ch = getchar() ) >= '0' && ch <= '9' ) )
    {
        if( ch == EOF ) return 1 << 30 ;
    }
    res = ch - '0' ;
    while( ( ch = getchar() ) >= '0' && ch <= '9' )
        res = res * 10 + ( ch - '0' ) ;
    return res ;
}
struct is
{
    ll l,r;
    ll maxx;
    ll num;
    ll sum;
}tree[10010];
ll a[1010];
ll b[1010];
void buildtree(ll l,ll r,ll pos)
{
    tree[pos].l=l;
    tree[pos].r=r;
    if(l==r)
    {
        tree[pos].num=a[l];
        tree[pos].maxx=(a[l]*a[l]-(a[l]-1)*(a[l]-1))*b[l];
        tree[pos].sum=a[l];
        return;
    }
    ll mid=(l+r)/2;
    buildtree(l,mid,pos*2);
    buildtree(mid+1,r,pos*2+1);
    tree[pos].maxx=max(tree[pos*2].maxx,tree[pos*2+1].maxx);
    tree[pos].sum=tree[pos*2+1].sum+tree[pos*2].sum;
}
void update(ll l,ll r,ll pos,ll change)
{
    if(tree[pos].r==change&&tree[pos].l==change)
    {
        ll kk=tree[pos].num-1;
        tree[pos].num=kk;
        tree[pos].maxx=(kk*kk-(kk-1)*(kk-1))*b[change];
        tree[pos].sum=kk;
        return;
    }
    ll mid=(l+r)/2;
    if(change<=mid)
    update(l,mid,pos*2,change);
    else
    update(mid+1,r,pos*2+1,change);
    tree[pos].sum=tree[pos*2].sum+tree[pos*2+1].sum;
    tree[pos].maxx=max(tree[pos*2].maxx,tree[pos*2+1].maxx);
}
ll findmax(ll l,ll r,ll pos,ll gg)
{
    if(tree[pos].l==tree[pos].r)
    return tree[pos].l;
    ll mid=(l+r)/2;
    if(tree[pos*2].maxx==gg)
    return findmax(l,mid,pos*2,gg);
    else
    return findmax(mid+1,r,pos*2+1,gg);
}
ll getans(ll l,ll r,ll pos)
{
    if(l==r)
    return tree[pos].num*tree[pos].num*b[l];
    ll mid=(l+r)/2;
    return getans(l,mid,pos*2)+getans(mid+1,r,pos*2+1);
}
int main()
{
    ll x,y,z,i,t;
    while(~scanf("%lld%lld",&x,&y))
    {
        for(i=1;i<=x;i++)
        scanf("%lld",&a[i]);
        for(i=1;i<=x;i++)
        scanf("%lld",&b[i]);
        buildtree(1,x,1);
        while(tree[1].sum!=y)
        {
            ll pos=findmax(1,x,1,tree[1].maxx);
            update(1,x,1,pos);
        }
        printf("%lld
",getans(1,x,1));
    }
    return 0;
}
 
原文地址:https://www.cnblogs.com/jhz033/p/5495249.html