Codeforces Round #547 (Div. 3) C D E

6 篇文章 0 订阅
3 篇文章 0 订阅

C. Polycarp Restores Permutation

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

An array of integers p1,p2,…,pnp1,p2,…,pn is called a permutation if it contains each number from 11 to nn exactly once. For example, the following arrays are permutations: [3,1,2][3,1,2], [1][1], [1,2,3,4,5][1,2,3,4,5] and [4,3,1,2][4,3,1,2]. The following arrays are not permutations: [2][2], [1,1][1,1], [2,3,4][2,3,4].

Polycarp invented a really cool permutation p1,p2,…,pnp1,p2,…,pn of length nn. It is very disappointing, but he forgot this permutation. He only remembers the array q1,q2,…,qn−1q1,q2,…,qn−1 of length n−1n−1, where qi=pi+1−piqi=pi+1−pi.

Given nn and q=q1,q2,…,qn−1q=q1,q2,…,qn−1, help Polycarp restore the invented permutation.

Input

The first line contains the integer nn (2≤n≤2⋅1052≤n≤2⋅105) — the length of the permutation to restore. The second line contains n−1n−1 integers q1,q2,…,qn−1q1,q2,…,qn−1 (−n<qi<n−n<qi<n).

Output

Print the integer -1 if there is no such permutation of length nn which corresponds to the given array qq. Otherwise, if it exists, print p1,p2,…,pnp1,p2,…,pn. Print any such permutation if there are many of them.

Examples

input

Copy

3
-2 1

output

Copy

3 1 2 

input

Copy

5
1 1 1 1

output

Copy

1 2 3 4 5 

input

Copy

4
-1 2 2

output

Copy

-1

题意:给出一个序列两两之间的差值,问你可以构造一个符合这个差值的序列吗。

思路:这道题的写法应该有几种,官方的题解是列出式子,然后算出第一个值就可以推出后面的值,我的想法是求一个前缀和,然后用1减去一个前缀和的最小值,然后依次加前缀和用set判重因为序列不可能出现重复的数,看值是否在1到n之间如果不在,则无法构成输出-1,否则输出答案。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<set>
#include<algorithm>
#define LL long long
#define INF 1e18

using namespace std;
const int maxn=2e5+100;
int a[maxn];
LL sum[maxn];
vector<LL>Q;
set<LL>ss;
int main()
{
    int n;
    scanf("%d",&n);

    for(int i=1;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    LL Min=INF;
    for(int i=1;i<n;i++)
    {
        sum[i]=sum[i-1]+a[i];
        if(sum[i]==0||sum[i]==sum[i-1])
        {
            printf("-1\n");
            return 0;
        }
        Min=min(Min,sum[i]);
    }
    Min=min(Min,sum[0]);
    LL st=1-Min;
    ss.insert(0);
    for(int i=0;i<n;i++)
    {
        if(st+sum[i]>n||st+sum[i]<0)
        {
            printf("-1\n");
            return 0;
        }
        ss.insert(sum[i]);
        Q.push_back(st+sum[i]);
    }
    if(ss.size()<n)
    {
        printf("-1\n");
        return 0;
    }
    for(int i=0;i<n;i++)
    {
        printf("%lld ",Q[i]);
    }
    printf("\n");

    return 0;
}

D. Colored Boots

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

There are nn left boots and nn right boots. Each boot has a color which is denoted as a lowercase Latin letter or a question mark ('?'). Thus, you are given two strings ll and rr, both of length nn. The character lili stands for the color of the ii-th left boot and the character riri stands for the color of the ii-th right boot.

A lowercase Latin letter denotes a specific color, but the question mark ('?') denotes an indefinite color. Two specific colors are compatible if they are exactly the same. An indefinite color is compatible with any (specific or indefinite) color.

For example, the following pairs of colors are compatible: ('f', 'f'), ('?', 'z'), ('a', '?') and ('?', '?'). The following pairs of colors are notcompatible: ('f', 'g') and ('a', 'z').

Compute the maximum number of pairs of boots such that there is one left and one right boot in a pair and their colors are compatible.

Print the maximum number of such pairs and the pairs themselves. A boot can be part of at most one pair.

Input

The first line contains nn (1≤n≤1500001≤n≤150000), denoting the number of boots for each leg (i.e. the number of left boots and the number of right boots).

The second line contains the string ll of length nn. It contains only lowercase Latin letters or question marks. The ii-th character stands for the color of the ii-th left boot.

The third line contains the string rr of length nn. It contains only lowercase Latin letters or question marks. The ii-th character stands for the color of the ii-th right boot.

Output

Print kk — the maximum number of compatible left-right pairs of boots, i.e. pairs consisting of one left and one right boot which have compatible colors.

The following kk lines should contain pairs aj,bjaj,bj (1≤aj,bj≤n1≤aj,bj≤n). The jj-th of these lines should contain the index ajaj of the left boot in the jj-th pair and index bjbj of the right boot in the jj-th pair. All the numbers ajaj should be distinct (unique), all the numbers bjbj should be distinct (unique).

If there are many optimal answers, print any of them.

题意:求出有多少对上下字母相同,‘?’可以和任意字母匹配。

思路:先让26个字母相同的匹配完,然后用‘?’匹配其他字母,然后在‘?’相同匹配。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#define LL long long

using namespace std;
const int maxn=2e5+100;
struct node
{
    int x,y;
};
char s1[maxn];
char s2[maxn];
vector<int>num1[30],num2[30];
vector<node>st;
int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",s1+1);
    scanf("%s",s2+1);

    for(int i=1;i<=n;i++)
    {
        if(s1[i]=='?')
        {
            num1[26].push_back(i);
        }
        else
        {
            num1[s1[i]-'a'].push_back(i);
        }
        if(s2[i]=='?')
        {
            num2[26].push_back(i);
        }
        else
        {
            num2[s2[i]-'a'].push_back(i);
        }
    }
    int ans=0;
    int pos1=0,pos2=0;
    for(int i=0;i<=25;i++)
    {
        int v=min(num1[i].size(),num2[i].size());
        for(int j=0;j<v;j++)
        {
            node p;
            p.x=num1[i][j];
            p.y=num2[i][j];
            st.push_back(p);
        }
        int k=v;
        if(num1[i].size()>v)
        {
            while(pos2<num2[26].size()&&k<num1[i].size())
            {
                node p;
                p.x=num1[i][k++];
                p.y=num2[26][pos2++];
                st.push_back(p);
            }
        }
        if(num2[i].size()>v)
        {
            while(pos1<num1[26].size()&&k<num2[i].size())
            {
                node p;
                p.y=num2[i][k++];
                p.x=num1[26][pos1++];
                st.push_back(p);
            }
        }
    }
    while(pos1<num1[26].size()&&pos2<num2[26].size())
    {
        node p;
        p.x=num1[26][pos1++];
        p.y=num2[26][pos2++];
        st.push_back(p);
    }
    ans=st.size();
    printf("%d\n",ans);
    for(int i=0;i<st.size();i++)
    {
        printf("%d %d\n",st[i].x,st[i].y);

    }
    return 0;
}

E. Superhero Battle

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

A superhero fights with a monster. The battle consists of rounds, each of which lasts exactly nn minutes. After a round ends, the next round starts immediately. This is repeated over and over again.

Each round has the same scenario. It is described by a sequence of nn numbers: d1,d2,…,dnd1,d2,…,dn (−106≤di≤106−106≤di≤106). The ii-th element means that monster's hp (hit points) changes by the value didi during the ii-th minute of each round. Formally, if before the ii-th minute of a round the monster's hp is hh, then after the ii-th minute it changes to h:=h+dih:=h+di.

The monster's initial hp is HH. It means that before the battle the monster has HH hit points. Print the first minute after which the monster dies. The monster dies if its hp is less than or equal to 00. Print -1 if the battle continues infinitely.

Input

The first line contains two integers HH and nn (1≤H≤10121≤H≤1012, 1≤n≤2⋅1051≤n≤2⋅105). The second line contains the sequence of integers d1,d2,…,dnd1,d2,…,dn (−106≤di≤106−106≤di≤106), where didi is the value to change monster's hp in the ii-th minute of a round.

Output

Print -1 if the superhero can't kill the monster and the battle will last infinitely. Otherwise, print the positive integer kk such that kk is the first minute after which the monster is dead.

Examples

input

Copy

1000 6
-100 -200 -300 125 77 -4

output

Copy

9

input

Copy

1000000000000 5
-1 0 0 0 0

output

Copy

4999999999996

input

Copy

10 4
-3 -6 5 4

output

Copy

-1

题意:给出n个数,然后给出一个值让这个值去依次去加这n个数,可以循环加,问操作多少次可以让这个值小于等于0,如果永远不能变成0则输出-1.

思路:先求前缀和如果大于0,则看第一次能否实现,如果不能则输出-1,否则就二分答案(判断的时候只要看最后一轮能否用最小值使答案成立),具体看代码。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long
#define INF 1e18
using namespace std;
const int maxn=2e5+100;
LL a[maxn],sum[maxn];
LL Min=INF,h;
int n;
bool check(LL x)
{
    if(h+(x-1)*sum[n]<=abs(Min))
    {
        return true;
    }
    else
    {
        return false;
    }
}
int main()
{
    scanf("%lld%d",&h,&n);

    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        sum[i]=sum[i-1]+a[i];
        Min=min(sum[i],Min);
    }
    LL v=h,flag=1,pos=1;
    if(sum[n]>=0)
    {
        for(int i=1;i<=n;i++)
        {
            v+=a[i];
           if(v<=0)
           {
               pos=i;
               break;
           }
        }
        if(v>0)
        {
            flag=0;
        }
        if(!flag)
        {
            printf("-1\n");
            return 0;
        }
        else
        {
           printf("%d\n",pos);
           return 0;
        }
    }
    LL l=0,r=h/(sum[n]*(-1))+2;
    //cout<<l<<" "<<r<<endl;
    while((r-l)>1)
    {
        LL mid=(l+r)/2;
        //cout<<l<<" "<<r<<endl;
        if(check(mid))
        {
            r=mid;
        }
        else
        {
            l=mid;
        }
    }
    LL ans=(r-1)*n;
    v=h+(r-1)*sum[n];
    for(int i=1;i<=n;i++)
    {
        v+=a[i];
        ans++;
        if(v<=0)
        {
            break;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值