Problem G: Array C
Time Limit: 1 Sec Memory Limit: 128 MBDescription
Giving two integers and and two arrays and both with length , you should construct an array also with length which satisfied:
1.0≤Ci≤Ai(1≤i≤n)
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; }