解题报告:Codeforces Round #371 (Div. 2) A~E

A. Meeting of Old Friends
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Today an outstanding event is going to happen in the forest — hedgehog Filya will come to his old fried Sonya!

Sonya is an owl and she sleeps during the day and stay awake from minute l1 to minute r1 inclusive. Also, during the minute k she prinks and is unavailable for Filya.

Filya works a lot and he plans to visit Sonya from minute l2 to minute r2 inclusive.

Calculate the number of minutes they will be able to spend together.

Input

The only line of the input contains integers l1r1l2r2 and k (1 ≤ l1, r1, l2, r2, k ≤ 1018l1 ≤ r1l2 ≤ r2), providing the segments of time for Sonya and Filya and the moment of time when Sonya prinks.

Output

Print one integer — the number of minutes Sonya and Filya will be able to spend together.

Examples
input
1 10 9 20 1
output
2
input
1 100 50 200 75
output
50
Note

In the first sample, they will be together during minutes 9 and 10.

In the second sample, they will be together from minute 50 to minute 74 and from minute 76 to minute 100.


题意:

给两个区间,求不包含某个点k的交集大小

思路:

取较小的上界,较大的下界为区间,减去 (k是否在该区间)

#include<bits/stdc++.h>

using namespace std;

int main()
{
    long long l1,r1,l2,r2,k;
    while(scanf("%I64d%I64d%I64d%I64d%I64d",&l1,&r1,&l2,&r2,&k)==5){
        long long ans = min(r2,r1)-max(l2,l1)+1;//printf("%I64d\n",ans);
        if(k>=max(l2,l1)&&k<=min(r2,r1)){
            ans--;
        }ans =max(0LL,ans);
        printf("%I64d\n",ans);
    }return 0;
}

B. Filya and Homework
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Today, hedgehog Filya went to school for the very first time! Teacher gave him a homework which Filya was unable to complete without your help.

Filya is given an array of non-negative integers a1, a2, ..., an. First, he pick an integer x and then he adds x to some elements of the array (no more than once), subtract x from some other elements (also, no more than once) and do no change other elements. He wants all elements of the array to be equal.

Now he wonders if it's possible to pick such integer x and change some elements of the array using this x in order to make all elements equal.

Input

The first line of the input contains an integer n (1 ≤ n ≤ 100 000) — the number of integers in the Filya's array. The second line containsn integers a1, a2, ..., an (0 ≤ ai ≤ 109) — elements of the array.

Output

If it's impossible to make all elements of the array equal using the process given in the problem statement, then print "NO" (without quotes) in the only line of the output. Otherwise print "YES" (without quotes).

Examples
input
5
1 3 3 2 1
output
YES
input
5
1 2 3 4 5
output
NO
Note

In the first sample Filya should select x = 1, then add it to the first and the last elements of the array and subtract from the second and the third elements.


题意:

给一个数列,问你能否 任意选择某一个整数X,将这个数列的上的每一个数进行  加上X   或者  减去X  或者 什么也不做 后使得所有数相等。

思路:

很明显相同的数字处理的方法相同,当不同数字的个数超过3个时,一定不会成功的,当不同数字个数小于三个时一定可以成功,等于3个时只有差值相等时才能成功。

#include<bits/stdc++.h>

using namespace std;

long long A[5];
int main()
{
    int n;
    while(scanf("%d",&n)==1){
        long long x;int cnt=0;
        for(int i=0;i<n;i++){
            scanf("%I64d",&x);
            if(cnt>3){
                continue;
            }int j;
            for(j=0;j<cnt;j++){
                if(A[j]==x){
                    break;
                }
            }
            if(j==cnt){
                A[cnt++]=x;
            }
        }if(cnt>3){
            printf("NO\n");
            continue;
        }if(cnt<=2){
            printf("YES\n");
            continue;
        }sort(A,A+cnt);
        if(A[2]-A[1]==A[1]-A[0]){
            printf("YES\n");
        }else {
            printf("NO\n");
        }
    }return 0;
}


C. Sonya and Queries
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Today Sonya learned about long integers and invited all her friends to share the fun. Sonya has an initially empty multiset with integers. Friends give her t queries, each of one of the following type:

  1.  +  ai — add non-negative integer ai to the multiset. Note, that she has a multiset, thus there may be many occurrences of the same integer.
  2.  -  ai — delete a single occurrence of non-negative integer ai from the multiset. It's guaranteed, that there is at least one ai in the multiset.
  3. ? s — count the number of integers in the multiset (with repetitions) that match some pattern s consisting of 0 and 1. In the pattern,0 stands for the even digits, while 1 stands for the odd. Integer x matches the pattern s, if the parity of the i-th from the right digit in decimal notation matches the i-th from the right digit of the pattern. If the pattern is shorter than this integer, it's supplemented with0-s from the left. Similarly, if the integer is shorter than the pattern its decimal notation is supplemented with the 0-s from the left.

For example, if the pattern is s = 010, than integers 92221250 and 414 match the pattern, while integers 311025 and 1030 do not.

Input

The first line of the input contains an integer t (1 ≤ t ≤ 100 000) — the number of operation Sonya has to perform.

Next t lines provide the descriptions of the queries in order they appear in the input file. The i-th row starts with a character ci — the type of the corresponding operation. If ci is equal to '+' or '-' then it's followed by a space and an integer ai (0 ≤ ai < 1018) given without leading zeroes (unless it's 0). If ci equals '?' then it's followed by a space and a sequence of zeroes and onse, giving the pattern of length no more than 18.

It's guaranteed that there will be at least one query of type '?'.

It's guaranteed that any time some integer is removed from the multiset, there will be at least one occurrence of this integer in it.

Output

For each query of the third type print the number of integers matching the given pattern. Each integer is counted as many times, as it appears in the multiset at this moment of time.

Examples
input
12
+ 1
+ 241
? 1
+ 361
- 241
? 0101
+ 101
? 101
- 101
? 101
+ 4000
? 0
output
2
1
2
1
1
input
4
+ 200
+ 200
- 200
? 0
output
1
Note

Consider the integers matching the patterns from the queries of the third type. Queries are numbered in the order they appear in the input.

  1. 1 and 241.
  2. 361.
  3. 101 and 361.
  4. 361.
  5. 4000.

题意:

好长啊、、

三种操作:

1、 +  X:将整数X加入多重集合

2、 -   X:将整数X从多重集合中删除一个,保证此时多重集合中至少有一个X

3、 ?  A:A为01序列,长度不超过18。查询多重集合中的元素对应的序列为A的个数。

一个整数X对应的序列为它各个位上奇偶性序列,比如123对应着101(1为奇,2为偶,3为奇),232对应着010。

思路:

将序列A看做一个二进制数,每个A可以映射到一个10进制的数上,可以发现每个数对应某一个集合,对某个数的操作就是对集合的元素数目的操作,查询就是直接输出对应集合的元素数目即可,例如232对应着010也就是集合2。

代码:

#include<bits/stdc++.h>

using namespace std;

int A[1000005];

int oper(long long x){
    int res = 0, y = 1;
    while(x){
        if(x&1){
            res += y;
        }x/=10;y<<=1;
    }return res;
}

int main()
{
    int n;
    char str[5];
    while(scanf("%d",&n)==1){
        memset(A,0,sizeof(A));
        long long x ;
        while(n--){
            scanf("%s%I64d",str,&x);
            int t = oper(x);
            //printf("t-->%d\n",t);
            if(str[0]=='+'){
                A[t]++;
            }else if(str[0]=='-'){
                A[t]--;
            }else {
                printf("%d\n",A[t]);
            }
        }

    }return 0;
}

D. Searching Rectangles
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Filya just learned new geometry object — rectangle. He is given a field consisting of n × n unit cells. Rows are numbered from bottom to top with integer from 1 to n. Columns are numbered from left to right with integers from 1 to n. Cell, located at the intersection of the rowr and column c is denoted as (r, c). Filya has painted two rectangles, such that their sides are parallel to coordinate axes and each cell lies fully inside or fully outside each of them. Moreover, no cell lies in both rectangles.

Later, hedgehog Filya became interested in the location of his rectangles but was unable to find the sheet of paper they were painted on. They were taken by Sonya and now she wants to play a little game with Filya. He tells her a query rectangle and she replies with the number of initial rectangles that lie fully inside the given query rectangle. The query rectangle should match the same conditions as initial rectangles. Rectangle lies fully inside the query if each o its cells lies inside the query.

Filya knows Sonya really well, so is sure that if he asks more than 200 questions she will stop to reply.

Input

The first line of the input contains an integer n (2 ≤ n ≤ 216) — size of the field.

For each query an integer between 0 and 2 is returned — the number of initial rectangles that lie fully inside the query rectangle.

Output

To make a query you have to print "? x1 y1 x2 y2" (without quotes) (1 ≤ x1 ≤ x2 ≤ n1 ≤ y1 ≤ y2 ≤ n), where (x1, y1) stands for the position of the bottom left cell of the query and (x2, y2) stands for the up right cell of the query. You are allowed to ask no more than200 queries. After each query you should perform "flush" operation and read the answer.

In case you suppose you've already determined the location of two rectangles (or run out of queries) you should print "! x11 y11 x12 y12x21 y21 x22 y22" (without quotes), where first four integers describe the bottom left and up right cells of the first rectangle, and following four describe the corresponding cells of the second rectangle. You can print the rectangles in an arbitrary order. After you have printed the answer, print the end of the line and perform "flush". Your program should terminate immediately after it print the answer.

Interaction

To flush you can use (just after printing an integer and end-of-line):

  • fflush(stdout) in C++;
  • System.out.flush() in Java;
  • stdout.flush() in Python;
  • flush(output) in Pascal;
  • See the documentation for other languages.

You will get the Wrong Answer verdict if you ask more than 200 queries, or if you print an incorrect coordinates.

You will get the Idleness Limit Exceeded verdict if you don't print anything (but you should) or if you forget about flushing the output (more info below).

Hacking.

The first line should contain an integer n (2 ≤ n ≤ 216).

The second line should contain four integers x1y1x2y2 (1 ≤ x1 ≤ x2 ≤ n1 ≤ y1 ≤ y2 ≤ n) — the description of the first rectangle.

The third line contains the description of the second rectangle in the similar way.

Example
input
5
2
1
0
1
1
1
0
1
output
? 1 1 5 5
? 1 1 3 3
? 1 1 3 1
? 2 2 2 2
? 3 3 5 5
? 3 3 3 5
? 3 3 3 4
? 3 4 3 5
! 2 2 2 2 3 4 3 5


这是一道交互题,就是你要在允许的次数内通过不断的询问根据他的返回值来得到答案,需要注意的是每次输出后需要加一个语句:fflush(stdout) in C++(详细看题目说明)

题意:

一个n*n的表格上有两个矩形,你每次可以询问一个范围(x1,y1,x2,y2) 代表以(x1,y1)为左上角,(x2,y2)为右下角的矩阵,返回x表示这个范围内完全包含的矩形数目,询问次数不超过200,2<=n<=2^16


思路:

二分。

二分每个矩阵的4条边即可,复杂度8*log(n)<=8*16<200,比赛的代码写的很丑很长。。


#include<bits/stdc++.h>

using namespace std;

int X[2][2];
int Y[2][2];



int n;

void find1(){
    int x1 = 1, y1 = 1 , x2 = n , y2 = n;
/*********find X2 **********///printf("find X2\n");
    int tx = x1,res;
    while(tx<x2){
        int x = ( (tx+x2)>>1 );
        if(x==tx){
            break;
        }printf("? %d %d %d %d\n",x1,y1,x,y2);fflush(stdout);
        scanf("%d",&res);
        if(res){
            x2 = x;
        }else {
            tx = x + 1;
        }
    }printf("? %d %d %d %d\n",x1,y1,tx,y2);fflush(stdout);
    scanf("%d",&res);
    if(res){
        x2 = tx;
    }


/********** find X1 ***********///printf("find X1\n");
    tx = x2;
    while( x1 < tx ){
        int x = (tx+x1)>>1;
        if(x==x1){
            break;
        }printf("? %d %d %d %d\n",x,y1,x2,y2);fflush(stdout);
        scanf("%d",&res);
        if(res){
            x1 = x;
        }else {
            tx = x-1;
        }
    }printf("? %d %d %d %d\n",tx,y1,x2,y2);fflush(stdout);
    scanf("%d",&res);
    if(res){
        x1 = tx;
    }

/******************* find Y2 *****************///printf("find Y2\n");
    int ty = y1;
    while(ty<y2){
        int y = ( (ty+y2)>>1 );
        if(y==ty){
            break;
        }printf("? %d %d %d %d\n",x1,y1,x2,y);fflush(stdout);
        scanf("%d",&res);
        if(res){
            y2 = y;
        }else {
            ty = y + 1;
        }
    }printf("? %d %d %d %d\n",x1,y1,x2,ty);fflush(stdout);
    scanf("%d",&res);
    if(res){
        y2=ty;
    }

/********************* find Y1 ***************///printf("find Y1\n");
    ty = y2;
    while( y1 < ty ){
        int y = (ty+y1)>>1;
        if(y==y1){
            break;
        }fflush(stdout);printf("? %d %d %d %d\n",x1,y,x2,y2);fflush(stdout);
        scanf("%d",&res);
        if(res){
            y1 = y;
        }else {
            ty = y-1;
        }
    }printf("? %d %d %d %d\n",x1,ty,x2,y2);fflush(stdout);
    scanf("%d",&res);
    if(res){
        y1 = ty;
    }X[0][0]=x1;X[0][1]=x2;
    Y[0][0]=y1;Y[0][1]=y2;
}

int check(int x1,int y1,int x2,int y2){
    return x1<=X[0][0]&&x2>=X[0][1]&&y1<=Y[0][0]&&y2>=Y[0][1];
}

void find2(){
    int x1 = 1, y1 = 1 , x2 = n , y2 = n;
/*********find X2 **********/ //printf("find X2\n");
    int tx = x1,res;
    while(tx<x2){
        int x = ( (tx+x2)>>1 );
        if(x==tx){
            break;
        }printf("? %d %d %d %d\n",x1,y1,x,y2);fflush(stdout);
        scanf("%d",&res);
        if(res>check(x1,y1,x,y2)){
            x2 = x;
        }else {
            tx = x + 1;
        }
    }printf("? %d %d %d %d\n",x1,y1,tx,y2);fflush(stdout);
    scanf("%d",&res);
    if(res>check(x1,y1,tx,y2)){
        x2 = tx;
    }
/********** find X1 ***********///printf("find X1\n");
    tx = x2;
    while( x1 < tx ){
        int x = (tx+x1)>>1;
        if(x==x1){
            break;
        }printf("? %d %d %d %d\n",x,y1,x2,y2);fflush(stdout);
        scanf("%d",&res);
        if(res>check(x,y1,x2,y2)){
            x1 = x;
        }else {
            tx = x-1;
        }
    }printf("? %d %d %d %d\n",tx,y1,x2,y2);fflush(stdout);
    scanf("%d",&res);
    if(res>check(tx,y1,x2,y2)){
        x1 = tx;
    }

/******************* find Y2 *****************///printf("find Y2\n");
    int ty = y1;
    while(ty<y2){
        int y = ( (ty+y2)>>1 );
        if(y==ty){
            break;
        }printf("? %d %d %d %d\n",x1,y1,x2,y);fflush(stdout);
        scanf("%d",&res);
        if(res>check(x1,y1,x2,y)){
            y2 = y;
        }else {
            ty = y + 1;
        }
    }printf("? %d %d %d %d\n",x1,y1,x2,ty);fflush(stdout);
    scanf("%d",&res);
    if(res>check(x1,y1,x2,ty)){
        y2=ty;
    }

/********************* find Y1 ***************///printf("find Y1\n");
    ty = y2;
    while( y1 < ty ){
        int y = (ty+y1)>>1;
        if(y==y1){
            break;
        }printf("? %d %d %d %d\n",x1,y,x2,y2);fflush(stdout);
        scanf("%d",&res);
        if(res>check(x1,y,x2,y2)){
            y1 = y;
        }else {
            ty = y-1;
        }
    }printf("? %d %d %d %d\n",x1,ty,x2,y2);fflush(stdout);
    scanf("%d",&res);
    if(res>check(x1,ty,x2,y2)){
        y1 = ty;
    }X[1][0]=x1;X[1][1]=x2;
    Y[1][0]=y1;Y[1][1]=y2;
}


int main()
{

    scanf("%d",&n);
    find1();
    find2();
    printf("! %d %d %d %d %d %d %d %d\n",X[0][0],Y[0][0],X[0][1],Y[0][1],X[1][0],Y[1][0],X[1][1],Y[1][1]);
    fflush(stdout);return 0;
}


E. Sonya and Problem Wihtout a Legend
time limit per test
5 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Sonya was unable to think of a story for this problem, so here comes the formal description.

You are given the array containing n positive integers. At one turn you can pick any element and increase or decrease it by 1. The goal is the make the array strictly increasing by making the minimum possible number of operations. You are allowed to change elements in any way, they can become negative or equal to 0.

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 3000) — the length of the array.

Next line contains n integer ai (1 ≤ ai ≤ 109).

Output

Print the minimum number of operation required to make the array strictly increasing.

Examples
input
7
2 1 5 11 5 9 11
output
9
input
5
5 4 3 2 1
output
12
Note

In the first sample, the array is going to look as follows:

2 3 5 6 7 9 11

|2 - 2| + |1 - 3| + |5 - 5| + |11 - 6| + |5 - 7| + |9 - 9| + |11 - 11| = 9

And for the second sample:

1 2 3 4 5

|5 - 1| + |4 - 2| + |3 - 3| + |2 - 4| + |1 - 5| = 12



题意:

给一个数列,你每次操作可以将数列上的某个数++或者--,最后要求得到一个严格递增的新数列,询问最小操作次数。

思路

离散化dp。

首先将每个数减去它的下标将问题转换为非严格递增。

可以确定每个的数最后变化的值一定是原数列中存在的,那么先得到数列B为排序后的原数列A。

dp[i][j]表示前 i 的数严格单调递增且第 i 个数为B[ j ]所需的最小操作数。

那么对于dp[i+1][j] 一定会选择 dp[i][k](k<=j)的某一个,A[i+1]变成B[k]的代价为他们的差值

即:dp[i+1][j] = min ( dp[i][k] + abs( A[i+1] - B[k] )  )   ( k<=j )

代码:

#include<bits/stdc++.h>

using namespace std;

int n;
long long A[3005];
long long B[3005];
long long dp[3005][3005];
int main()
{
    while(scanf("%d",&n)==1){
        for(int i=1;i<=n;i++){
            scanf("%I64d",&A[i]);
            A[i] -= i;
            B[i] = A[i] ;
        }sort(B+1,B+n+1);
        for(int i=1;i<=n;i++){long long mi = dp[i-1][1];
            for(int j=1;j<=n;j++){
                mi = min(mi,dp[i-1][j]);
                dp[i][j] = mi + abs(A[i]-B[j]);
            }
        }long long ans = dp[n][1];
        for(int i=1;i<=n;i++){
            ans = min(ans,dp[n][i]);
        }printf("%I64d\n",ans);
    }return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值