Codeforces 1260总结

A. Heating
Several days ago you bought a new house and now you are planning to start a renovation. Since winters in your region can be very cold you need to decide how to heat rooms in your house.

Your house has n rooms. In the i-th room you can install at most ci heating radiators. Each radiator can have several sections, but the cost of the radiator with k sections is equal to k2 burles.

Since rooms can have different sizes, you calculated that you need at least sumi sections in total in the i-th room.

For each room calculate the minimum cost to install at most ci radiators with total number of sections not less than sumi.

Input
The first line contains single integer n (1≤n≤1000) — the number of rooms.

Each of the next n lines contains the description of some room. The i-th line contains two integers ci and sumi (1≤ci,sumi≤104) — the maximum number of radiators and the minimum total number of sections in the i-th room, respectively.

Output
For each room print one integer — the minimum possible cost to install at most ci radiators with total number of sections not less than sumi.

Example
Input
4
1 10000
10000 1
2 6
4 6
Output
100000000
1
18
10
Note
In the first room, you can install only one radiator, so it’s optimal to use the radiator with sum1 sections. The cost of the radiator is equal to (104)2=108.

In the second room, you can install up to 104 radiators, but since you need only one section in total, it’s optimal to buy one radiator with one section.

In the third room, there 7 variants to install radiators: [6,0], [5,1], [4,2], [3,3], [2,4], [1,5], [0,6]. The optimal variant is [3,3] and it costs 32+32=18.
大致题意:
给你两个数,让你把后者拆分成前者的份数,使得各个部分的数值的平方和最小。
思路就是尽量让每一部分都最小,尽量平均分配。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
ll n,c,s,sum,ans,cnt,i,j,k,Max,Min;
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    while(n--)
    {
        cin>>c>>s;
        ans=s/c;
        cnt=s%c;
        if(!cnt)
            sum=ans*ans*c;
        else
            sum=ans*ans*(c-cnt)+cnt*(ans+1)*(ans+1);
        cout<<sum<<endl;
    }
}

B. Obtain Two Zeroes
You are given two integers a and b. You may perform any number of operations on them (possibly zero).

During each operation you should choose any positive integer x and set a:=a−x, b:=b−2x or a:=a−2x, b:=b−x. Note that you may choose different values of x in different operations.

Is it possible to make a and b equal to 0 simultaneously?

Your program should answer t independent test cases.

Input
The first line contains one integer t (1≤t≤100) — the number of test cases.

Then the test cases follow, each test case is represented by one line containing two integers a and b for this test case (0≤a,b≤109).

Output
For each test case print the answer to it — YES if it is possible to make a and b equal to 0 simultaneously, and NO otherwise.

You may print every letter in any case you want (so, for example, the strings yEs, yes, Yes and YES will all be recognized as positive answer).

Example
Input
3
6 9
1 1
1 2
Output
YES
NO
YES
Note
In the first test case of the example two operations can be used to make both a and b equal to zero:

choose x=4 and set a:=a−x, b:=b−2x. Then a=6−4=2, b=9−8=1;
choose x=1 and set a:=a−2x, b:=b−x. Then a=2−2=0, b=1−1=0.
题目大意是给出两个数,可以任选一个整数,将a和b进行a:=a−x, b:=b−2x 或 a:=a−2x, b:=b−x. 操作,问是否能将二者同时化为0
我做题就经常思考的时候很复杂,想出来才发现并不难。这个题其实就是看能否找出两个数,使得
2x+y=a
2y+x=b
我第一遍提交的时候没有想到a与b数值相差悬殊的情况,所以WA2,加上这种情况就能AC了

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
ll t,n,c,s,sum,ans,cnt,i,j,k,Max,Min,a,b;
int main()
{
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        cin>>a>>b;
        sum=a+b;
        if(sum%3||a>2*b||b>2*a)
            cout<<"NO"<<endl;
        else
            cout<<"YES"<<endl;
    }
    return 0;
}

C. Infinite Fence
You are a rebel leader and you are planning to start a revolution in your country. But the evil Government found out about your plans and set your punishment in the form of correctional labor.

You must paint a fence which consists of 10100 planks in two colors in the following way (suppose planks are numbered from left to right from 0):

if the index of the plank is divisible by r (such planks have indices 0, r, 2r and so on) then you must paint it red;
if the index of the plank is divisible by b (such planks have indices 0, b, 2b and so on) then you must paint it blue;
if the index is divisible both by r and b you can choose the color to paint the plank;
otherwise, you don’t need to paint the plank at all (and it is forbidden to spent paint on it).
Furthermore, the Government added one additional restriction to make your punishment worse. Let’s list all painted planks of the fence in ascending order: if there are k consecutive planks with the same color in this list, then the Government will state that you failed the labor and execute you immediately. If you don’t paint the fence according to the four aforementioned conditions, you will also be executed.

The question is: will you be able to accomplish the labor (the time is not important) or the execution is unavoidable and you need to escape at all costs.

Input
The first line contains single integer T (1≤T≤1000) — the number of test cases.

The next T lines contain descriptions of test cases — one per line. Each test case contains three integers r, b, k (1≤r,b≤109, 2≤k≤109) — the corresponding coefficients.

Output
Print T words — one per line. For each test case print REBEL (case insensitive) if the execution is unavoidable or OBEY (case insensitive) otherwise.

Example
input
4
1 1 2
2 10 4
5 2 3
3 2 2
output
OBEY
REBEL
OBEY
OBEY
大致题意:
现有10^100块木板需要涂漆,对第x块来讲,如果是x是r的倍数,则涂一种颜色,是b的倍数,则涂另一种颜色。如果既是r又是b的倍数,那么两种颜色都可以涂;如果连续有k块板的颜色是一样的,则输出REBEL,否则输出OBEY。问是否能避免被处死

这个题我上午没有做出来,后来在网上搜的时候,看到有大佬用了打表。打表是我前两周经常用的一个方法,但是仅仅一两周没用这个方法,就已经想不起来了。用打表可以发现,以最小公倍数为循环周期,只考虑一个循环周期即可。假设r<b,如果b%r==0,那么b/r-1就是唯一的答案了,用b/r-1与k进行比较。如果b%r != 0,那就需要进一步分析了,直接代码见

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e7+10;
ll r,b,k;
int vis[N];
void solve(){
    scanf("%lld%lld%lld",&r,&b,&k);
    if(r > b) swap(r,b);
    if(r == b){
        printf("OBEY\n");
        return;
    }
    if(b%r == 0){
        if(k <= (b/r-1)){
            printf("REBEL\n");
        }else {
            printf("OBEY\n");
        }
        return;
    }
    ll x = b*r/__gcd(b,r);
    ll t = x/r-1;
    ll s = x/b;
    ll y = t/s;
    if(t%s) y++;
    if(k <= y){
        printf("REBEL\n");
    }else {
        printf("OBEY\n");
    }

}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        solve();
    }
    return 0;
}

D . A Game with Traps
You are playing a computer game, where you lead a party of m soldiers. Each soldier is characterised by his agility ai.

The level you are trying to get through can be represented as a straight line segment from point 0 (where you and your squad is initially located) to point n+1 (where the boss is located).

The level is filled with k traps. Each trap is represented by three numbers li, ri and di. li is the location of the trap, and di is the danger level of the trap: whenever a soldier with agility lower than di steps on a trap (that is, moves to the point li), he gets instantly killed. Fortunately, you can disarm traps: if you move to the point ri, you disarm this trap, and it no longer poses any danger to your soldiers. Traps don’t affect you, only your soldiers.

You have t seconds to complete the level — that is, to bring some soldiers from your squad to the boss. Before the level starts, you choose which soldiers will be coming with you, and which soldiers won’t be. After that, you have to bring all of the chosen soldiers to the boss. To do so, you may perform the following actions:

if your location is x, you may move to x+1 or x−1. This action consumes one second;
if your location is x and the location of your squad is x, you may move to x+1 or to x−1 with your squad in one second. You may not perform this action if it puts some soldier in danger (i. e. the point your squad is moving into contains a non-disarmed trap with di greater than agility of some soldier from the squad). This action consumes one second;
if your location is x and there is a trap i with ri=x, you may disarm this trap. This action is done instantly (it consumes no time).
Note that after each action both your coordinate and the coordinate of your squad should be integers.

You have to choose the maximum number of soldiers such that they all can be brought from the point 0 to the point n+1 (where the boss waits) in no more than t seconds.

Input
The first line contains four integers m, n, k and t (1≤m,n,k,t≤2⋅105, n<t) — the number of soldiers, the number of integer points between the squad and the boss, the number of traps and the maximum number of seconds you may spend to bring the squad to the boss, respectively.

The second line contains m integers a1, a2, …, am (1≤ai≤2⋅105), where ai is the agility of the i-th soldier.

Then k lines follow, containing the descriptions of traps. Each line contains three numbers li, ri and di (1≤li≤ri≤n, 1≤di≤2⋅105) — the location of the trap, the location where the trap can be disarmed, and its danger level, respectively.

Output
Print one integer — the maximum number of soldiers you may choose so that you may bring them all to the boss in no more than t seconds.

Example
Input
5 6 4 14
1 2 3 4 5
1 5 2
1 2 5
2 3 5
3 5 3
Output
3
Note
In the first example you may take soldiers with agility 3, 4 and 5 with you. The course of action is as follows:

go to 2 without your squad;
disarm the trap 2;
go to 3 without your squad;
disartm the trap 3;
go to 0 without your squad;
go to 7 with your squad.
The whole plan can be executed in 13 seconds.
大致题意:
共m个士兵,k个陷阱,你需要从0走到n + 1。每个士兵有生命值,每个陷阱有对应的陷阱值。生命值小于陷阱值,就走不了。你可以带着士兵走,可以向前或者向后。没走一步花费1s。要求总时间小于t,最多可以带多少个士兵。
这个题一看题目这么长当时就不大想做,事后查了查大佬的代码,内心窃喜还好自己没多花时间在上面(虽然这种想法是不对的),大佬们大体用了贪心和二分法,但是里面穿插了我用不惯的vector。
大佬的思路就是判断这x人中最小的一个就行了。如果当前这个陷阱无法通过,那么我们就先走到l-1,然后再去踩陷阱。所以需要先将陷阱按照位置排序之后,找出会对我们有阻碍的陷阱,然后遍历,求出踩陷阱应该花费的时间,乘以2,再加上本应该走的时间n+1就可以了。
先粘上代码,等我在深造一下再回来仔细研究。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<string>
#include<vector>
#define ll long long
using namespace std;

const int maxx=2e5+100;
struct node
{
    int l,r,v;
    bool operator<(const node &a)const
    {
        return l<a.l;//按照位置排序,因为本身时间就与位置有关。
    }
} p[maxx];
int a[maxx];
vector<int> q[maxx];
int m,n,k,t;

inline bool check(int kl)
{
    if(kl==0)
        return 1;
    int mv=a[m-kl+1];
    ll ans=0;
    node c[k+2];
    int cnt=0;
    for(int i=1; i<=k; i++)
        if(p[i].v>mv)
            c[++cnt]=p[i];
    int _max=0;
    for(int i=1; i<=cnt; i++)
    {
        if(c[i].r<=_max)
            continue;//这代表着当前这个陷阱已经被我们解除过了。
        _max=max(_max,c[i].l-1);//这代表着我们走到了能走的最大值。
        ans+=(ll)(c[i].r-_max);//这代表着我们踩陷阱花费的时间。
        _max=c[i].r;
    }
    ans=ans*2ll+n+1;//ans*2,因为要往返。
    return ans<=(ll)t;
}
int main()
{
    scanf("%d%d%d%d",&m,&n,&k,&t);
    for(int i=1; i<=m; i++)
        scanf("%d",&a[i]);
    sort(a+1,a+1+m);
    for(int i=1; i<=k; i++)
        scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].v);
    sort(p+1,p+1+k);
    int ans=0;
    int l=0,r=m;
    while(l<=r)
    {
        int mid=l+r>>1;
        if(check(mid))
        {
            ans=max(ans,mid);
            l=mid+1;
        }
        else
            r=mid-1;
    }
    cout<<ans<<endl;
    return 0;
}

E Tournament
You are organizing a boxing tournament, where n boxers will participate (n is a power of 2), and your friend is one of them. All boxers have different strength from 1 to n, and boxer i wins in the match against boxer j if and only if i is stronger than j.

The tournament will be organized as follows: n boxers will be divided into pairs; the loser in each pair leaves the tournament, and n2 winners advance to the next stage, where they are divided into pairs again, and the winners in all pairs advance to the next stage, and so on, until only one boxer remains (who is declared the winner).

Your friend really wants to win the tournament, but he may be not the strongest boxer. To help your friend win the tournament, you may bribe his opponents: if your friend is fighting with a boxer you have bribed, your friend wins even if his strength is lower.

Furthermore, during each stage you distribute the boxers into pairs as you wish.

The boxer with strength i can be bribed if you pay him ai dollars. What is the minimum number of dollars you have to spend to make your friend win the tournament, provided that you arrange the boxers into pairs during each stage as you wish?

Input
The first line contains one integer n (2≤n≤218) — the number of boxers. n is a power of 2.

The second line contains n integers a1, a2, …, an, where ai is the number of dollars you have to pay if you want to bribe the boxer with strength i. Exactly one of ai is equal to −1 — it means that the boxer with strength i is your friend. All other values are in the range [1,109].

Output
Print one integer — the minimum number of dollars you have to pay so your friend wins.

Examples
Input
4
3 9 1 -1
Output
0
Input
8
11 -1 13 19 24 7 17 5
Output
12

大致题意就是现在有n个人打拳,序号小的打不过序号大的,如果想赢的话,你需要花ai元贿赂序号为i的人。你朋友参加了比赛,你可以分配每次比赛的组队以及贿赂,问你最少需要多少钱才能赢得比赛。
这个题需要用到贪心,贿赂能够进下一场比赛中的一个即可,所以是贿赂用钱最少的那个。需要每次判断该数是否为2的幂次方,如果是,那么就是要在之后的人中至少要贿赂一个,这样就能做到用钱最少了。
F Colored Tree
You’re given a tree with n vertices. The color of the i-th vertex is hi.

The value of the tree is defined as ∑hi=hj,1≤i<j≤ndis(i,j), where dis(i,j) is the number of edges on the shortest path between i and j.

The color of each vertex is lost, you only remember that hi can be any integer from li,ri. You want to calculate the sum of values of all trees meeting these conditions modulo 109+7 (the set of edges is fixed, but each color is unknown, so there are ∏i=1n(ri−li+1) different trees).

Input
The first line contains one integer n (2≤n≤105) — the number of vertices.

Then n lines follow, each line contains two integers li and ri (1≤li≤ri≤105) denoting the range of possible colors of vertex i.

Then n−1 lines follow, each containing two integers u and v (1≤u,v≤n, u≠v) denoting an edge of the tree. It is guaranteed that these edges form a tree.

Output
Print one integer — the sum of values of all possible trees, taken modulo 109+7.

Example
Input
4
1 1
1 2
1 1
1 2
1 2
1 3
3 4
Output
22
Note
In the first example there are four different ways to color the tree (so, there are four different trees):

a tree with vertices colored as follows: {1,1,1,1}. The value of this tree is dis(1,2)+dis(1,3)+dis(1,4)+dis(2,3)+dis(2,4)+dis(3,4)=10;
a tree with vertices colored as follows: {1,2,1,1}. The value of this tree is dis(1,3)+dis(1,4)+dis(3,4)=4;
a tree with vertices colored as follows: {1,1,1,2}. The value of this tree is dis(1,2)+dis(1,3)+dis(2,3)=4;
a tree with vertices colored as follows: {1,2,1,2}. The value of this tree is dis(1,3)+dis(2,4)=4.
Overall the sum of all values is 10+4+4+4=22.
这个题我只稍微看了一下就知道真是打扰了…依然是我学的不怎么好的树。大概就是给你一个n结点的树,树的值定义为任意两个相同颜色的点之间的路径长度之和,但是你仅知道某节点的颜色所属的区间,所以这棵树有多种可能,要求求出所有可能的情况的数值之和(形容的很绕)
上网搜了下,需要用到树链剖分…很新鲜的词,今儿太晚了,明儿下午好好研究一下。

总的来说,今天表现得不大理想,前一阵子太放松,天天睡到九点多,突然一下要“早起”真是给我困得不行,大概接近十点的时候眼睛都快睁不开了,更不用提我那转都不转的脑子了,虽然水平也不大行,但是状态比水平更不行,可能还得习惯两天,晚上再早点睡。争取明天能以更好的状态来打比赛吧。加油!

猜你喜欢

转载自blog.csdn.net/weixin_46434074/article/details/107173485
今日推荐