Educational Codeforces Round 52 (Rated for Div. 2)

体验极差,只要是读题太慢,场上过了两题,场下补了一个(时间啊)。

A. Vasya and Chocolate

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

There is a special offer in Vasya's favourite supermarket: if the customer buys aa chocolate bars, he or she may take bb additional bars for free. This special offer can be used any number of times.

Vasya currently has ss roubles, and he wants to get as many chocolate bars for free. Each chocolate bar costs cc roubles. Help Vasya to calculate the maximum possible number of chocolate bars he can get!

Input

The first line contains one integer tt (1≤t≤1001≤t≤100) — the number of testcases.

Each of the next tt lines contains four integers s,a,b,c (1≤s,a,b,c≤109)s,a,b,c (1≤s,a,b,c≤109) — the number of roubles Vasya has, the number of chocolate bars you have to buy to use the special offer, the number of bars you get for free, and the cost of one bar, respectively.

Output

Print tt lines. ii-th line should contain the maximum possible number of chocolate bars Vasya can get in ii-th test.

Example

input

Copy

2
10 3 1 1
1000000000 1 1000000000 1

output

Copy

13
1000000001000000000

Note

In the first test of the example Vasya can buy 99 bars, get 33 for free, buy another bar, and so he will get 1313 bars.

In the second test Vasya buys 10000000001000000000 bars and gets 10000000000000000001000000000000000000 for free. So he has 10000000010000000001000000001000000000 bars.

题解:~-~

​
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=min(tree[rt<<1],tree[rt<<1|1])
using namespace std;

inline int read(){
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}

typedef long long ll;
const int M=1e5+5;
const int N=2e6+5;
int main(){
    int t;
    ll s,a,b,c;
    scanf("%d",&t);
    while(t--){
        scanf("%lld %lld %lld %lld",&s,&a,&b,&c);
        ll d=s/c;
        ll ans=d+d/a*b;
        printf("%lld\n",ans);
    }
    return 0;
}

​

B. Vasya and Isolated Vertices

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Vasya has got an undirected graph consisting of nn vertices and mm edges. This graph doesn't contain any self-loops or multiple edges. Self-loop is an edge connecting a vertex to itself. Multiple edges are a pair of edges such that they connect the same pair of vertices. Since the graph is undirected, the pair of edges (1,2)(1,2) and (2,1)(2,1) is considered to be multiple edges. Isolated vertex of the graph is a vertex such that there is no edge connecting this vertex to any other vertex.

Vasya wants to know the minimum and maximum possible number of isolated vertices in an undirected graph consisting of nn vertices and mm edges.

Input

The only line contains two integers nn and m (1≤n≤105,0≤m≤n(n−1)2)m (1≤n≤105,0≤m≤n(n−1)2).

It is guaranteed that there exists a graph without any self-loops or multiple edges with such number of vertices and edges.

Output

In the only line print two numbers minmin and maxmax — the minimum and maximum number of isolated vertices, respectively.

Examples

input

Copy

4 2

output

Copy

0 1

input

Copy

3 1

output

Copy

1 1

Note

In the first example it is possible to construct a graph with 00 isolated vertices: for example, it should contain edges (1,2)(1,2) and (3,4)(3,4). To get one isolated vertex, we may construct a graph with edges (1,2)(1,2) and (1,3)(1,3).

In the second example the graph will always contain exactly one isolated vertex.

题解:min情况:两个点一组是最小的(奇数有一组是三个点);

            max情况:枚举顶点数(2 ~ n)

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=min(tree[rt<<1],tree[rt<<1|1])
using namespace std;

inline int read(){
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}

typedef long long ll;
const int M=1e5+5;
const int N=2e6+5;
int main(){
    ll n,m;
    scanf("%lld %lld",&n,&m);
    if(n==1){
        printf("1 1\n");
        return 0;
    }
    if(m==0){
        printf("%lld %lld\n",n,n);
        return 0;
    }
    if(m>=(n-1)*n/2){
        printf("0 0\n");
        return 0;
    }
    ll ans1=0;
    if(n%2==1)
        ans1=n/2+1;
    else
        ans1=n/2;
    if(ans1<=m){
        printf("0 ");
    }
    else{
        if(n%2==1){
            ll ans2=0;
            ans2=(ans1-m)*2;
            ans2--;
            printf("%lld ",ans2);
        }
        else{
            ll ans2=0;
            ans2=(ans1-m)*2;
            printf("%lld ",ans2);
        }
    }
    for(ll i=2;i<=n;i++){   // 枚举顶点数
        ll sum=i*(i-1)/2;
        if(sum>=m){
            printf("%lld\n",n-i);
            break;
        }
    }
    return 0;
}

C. Make It Equal

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

There is a toy building consisting of nn towers. Each tower consists of several cubes standing on each other. The ii-th tower consists of hihi cubes, so it has height hihi.

Let's define operation slice on some height HH as following: for each tower ii, if its height is greater than HH, then remove some top cubes to make tower's height equal to HH. Cost of one "slice" equals to the total number of removed cubes from all towers.

Let's name slice as good one if its cost is lower or equal to kk (k≥nk≥n).

Calculate the minimum number of good slices you have to do to make all towers have the same height. Of course, it is always possible to make it so.

Input

The first line contains two integers nn and kk (1≤n≤2⋅1051≤n≤2⋅105, n≤k≤109n≤k≤109) — the number of towers and the restriction on slices, respectively.

The second line contains nn space separated integers h1,h2,…,hnh1,h2,…,hn (1≤hi≤2⋅1051≤hi≤2⋅105) — the initial heights of towers.

Output

Print one integer — the minimum number of good slices you have to do to make all towers have the same heigth.

Examples

input

Copy

5 5
3 1 2 2 4

output

Copy

2

input

Copy

4 5
2 3 4 5

output

Copy

2

Note

In the first example it's optimal to make 22 slices. The first slice is on height 22 (its cost is 33), and the second one is on height 11 (its cost is 44).

题解:把个数压缩到一维数组中(用线段树),再遍历求解。

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
using namespace std;

inline int read(){
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}

typedef long long ll;
const int M=2e5+5;
const int N=2e6+5;
int n,a[M];
ll tree[M<<2]={0},v[M<<2]={0},b[M]={0},k;
void fun(int l,int r,int rt){
    if(v[rt]){
        v[rt<<1]+=v[rt];
        v[rt<<1|1]+=v[rt];
        int mid=l+r>>1;
        tree[rt<<1]+=v[rt]*(mid-l+1);
        tree[rt<<1|1]+=v[rt]*(r-mid);
        v[rt]=0;
    }
}

void upset(int a,int b,int vel,int l,int r,int rt){
    if(a<=l&&r<=b){
        v[rt]+=vel;
        tree[rt]+=vel*(r-l+1);
        return ;
    }
    fun(l,r,rt);
    int mid=l+r>>1;
    if(a<=mid)
        upset(a,b,vel,l,mid,rt<<1);
    if(b>mid)
        upset(a,b,vel,mid+1,r,rt<<1|1);
    pushup();
}

ll findd(int a,int b,int l,int r,int rt){
    if(a<=l&&r<=b){
        return tree[rt];
    }
    fun(l,r,rt);
    int mid=l+r>>1;
    ll ans=0;
    if(a<=mid)
        ans+=findd(a,b,l,mid,rt<<1);
    if(b>mid)
        ans+=findd(a,b,mid+1,r,rt<<1|1);
    return ans;
}
int main(){
    scanf("%d %lld",&n,&k);
    int nn=0;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        nn=max(nn,a[i]);
    }
    for(int i=1;i<=n;i++){
        upset(1,a[i],1,1,nn,1);
    }
    for(int i=1;i<=nn;i++){
        b[i]=findd(i,i,1,nn,1);
    }
    ll sum=0,ans=0;
    int pos=nn;
    while(pos>0){
        if(b[pos]>=n) break;
        sum+=b[pos];
        if(sum==k){
            sum=0;
            ans++;
            pos--;
        }
        else if(sum>k){
            sum=0;
            ans++;
        }
        else
            pos--;
    }
    if(sum>0)
        ans++;
    printf("%lld\n",ans);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值