Codeforces Round #Pi (Div. 2)

A. Lineland Mail
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

All cities of Lineland are located on the Ox coordinate axis. Thus, each city is associated with its position xi — a coordinate on the Ox axis. No two cities are located at a single point.

Lineland residents love to send letters to each other. A person may send a letter only if the recipient lives in another city (because if they live in the same city, then it is easier to drop in).

Strange but true, the cost of sending the letter is exactly equal to the distance between the sender's city and the recipient's city.

For each city calculate two values ​​mini and maxi, where mini is the minimum cost of sending a letter from the i-th city to some other city, and maxi is the the maximum cost of sending a letter from the i-th city to some other city

Input

The first line of the input contains integer n (2 ≤ n ≤ 105) — the number of cities in Lineland. The second line contains the sequence of n distinct integers x1, x2, ..., xn ( - 109 ≤ xi ≤ 109), where xi is the x-coordinate of the i-th city. All the xi's are distinct and follow in ascending order.

Output

Print n lines, the i-th line must contain two integers mini, maxi, separated by a space, where mini is the minimum cost of sending a letter from the i-th city, and maxi is the maximum cost of sending a letter from the i-th city.

Sample test(s)
Input
4
-5 -2 2 7
Output
3 12
3 9
4 7
5 12
Input
2
-1 1
Output
2 2
2 2
题意:给坐标轴上N个点,输出每个点到其它点的最近和最远距离。

分析:排序,距离最远的点只能是两端,最近的就lowerbound找即可

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 100100;
int r[N], d[N];
int mn[N],mx[N];
int cmp(int a, int b)
{
    return d[a] < d[b];
}
int main()
{
    int i,j,k,m,n;
    while(scanf("%d",&n) == 1)
    {
        for(i=1; i<=n; i++)
            scanf("%d",d+i);
        for(i=1; i<=n; i++)
            r[i] = i;
        sort(r+1,r+1+n,cmp);
        for(i=1; i<=n; i++)
        {
            int a = r[i];
            if(i == 1)
            {
                mn[a] = d[r[i+1]] - d[r[1]];
                mx[a] = d[r[n]] - d[r[1]];
            }
            else if(i == n)
            {
                mn[a] = d[r[n]] - d[r[n-1]];
                mx[a] = d[r[n]] - d[r[1]];
            }
            else
                mx[a] = max(d[a]-d[r[1]], d[r[n]]-d[a]),
                mn[a] = min(d[a]-d[r[i-1]], d[r[i+1]]-d[a]);
        }
        for(i=1; i<=n; i++)
            printf("%d %d\n",mn[i], mx[i]);
    }
    return 0;
}

B. Berland National Library
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Berland National Library has recently been built in the capital of Berland. In addition, in the library you can take any of the collected works of Berland leaders, the library has a reading room.

Today was the pilot launch of an automated reading room visitors' accounting system! The scanner of the system is installed at the entrance to the reading room. It records the events of the form "reader entered room", "reader left room". Every reader is assigned a registration number during the registration procedure at the library — it's a unique integer from 1 to 106. Thus, the system logs events of two forms:

  • "+ ri" — the reader with registration number ri entered the room;
  • "- ri" — the reader with registration number ri left the room.

The first launch of the system was a success, it functioned for some period of time, and, at the time of its launch and at the time of its shutdown, the reading room may already have visitors.

Significant funds of the budget of Berland have been spent on the design and installation of the system. Therefore, some of the citizens of the capital now demand to explain the need for this system and the benefits that its implementation will bring. Now, the developers of the system need to urgently come up with reasons for its existence.

Help the system developers to find the minimum possible capacity of the reading room (in visitors) using the log of the system available to you.

Input

The first line contains a positive integer n (1 ≤ n ≤ 100) — the number of records in the system log. Next follow n events from the system journal in the order in which the were made. Each event was written on a single line and looks as "+ ri" or "- ri", where ri is an integer from 1 to 106, the registration number of the visitor (that is, distinct visitors always have distinct registration numbers).

It is guaranteed that the log is not contradictory, that is, for every visitor the types of any of his two consecutive events are distinct. Before starting the system, and after stopping the room may possibly contain visitors.

Output

Print a single integer — the minimum possible capacity of the reading room.

Sample test(s)
Input
6
+ 12001
- 12001
- 1
- 1200
+ 1
+ 7
Output
3
Input
2
- 1
- 2
Output
2
Input
2
+ 1
- 1
Output
1
Note

In the first sample test, the system log will ensure that at some point in the reading room were visitors with registration numbers 1, 1200 and 12001. More people were not in the room at the same time based on the log. Therefore, the answer to the test is 3.

题意:有M个关于房间的记录形如:“+ X” “- X” 分别表示id为X的人进入和离开房间,求在某时刻的房间里的最大人数。

分析:可以先计算出初始房内的人数(没有+就-的ID数量)或者最终房内的人数(只+没-的ID数量)。

如果是前者,遇到+则加1,遇到-就减1, 如果是后种做法,从后往前遍历,是-就+1, 是+就-1;

无论哪种做法,维护过程的最大值就行。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1000100;
int vis[N];
char s[123][2];
int d[123];
int ans[123];
int main()
{
    int i,j,k,m,n;
    while(scanf("%d",&n) == 1)
    {
        memset(vis,0,sizeof(vis));
        int tp = 0;
        for(i=1; i<=n; i++)
        {
            scanf("%s %d",s[i],d+i);
            if(s[i][0] == '+') vis[d[i]] = 1, tp++;
            else {
                if(vis[d[i]] == 1) tp--;
                vis[d[i]] = 0;
            }
        }
        int ret = 0;
            ans[n+1] = tp;
            for(i=n; i>=1; i--)
            {
                ans[i] = ans[i+1];
                ret = max(ret,ans[i]);
                if(s[i][0] == '-')
                    ans[i]++;
                else ans[i]--;
                ret = max(ret, ans[i]);
            }
      printf("%d\n",ret);
    }
    return 0;
}

C. Geometric Progression
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Polycarp loves geometric progressions very much. Since he was only three years old, he loves only the progressions of length three. He also has a favorite integer k and a sequence a, consisting of n integers.

He wants to know how many subsequences of length three can be selected from a, so that they form a geometric progression with common ratio k.

A subsequence of length three is a combination of three such indexes i1, i2, i3, that 1 ≤ i1 < i2 < i3 ≤ n. That is, a subsequence of length three are such groups of three elements that are not necessarily consecutive in the sequence, but their indexes are strictly increasing.

A geometric progression with common ratio k is a sequence of numbers of the form b·k0, b·k1, ..., b·kr - 1.

Polycarp is only three years old, so he can not calculate this number himself. Help him to do it.

Input

The first line of the input contains two integers, n and k (1 ≤ n, k ≤ 2·105), showing how many numbers Polycarp's sequence has and his favorite number.

The second line contains n integers a1, a2, ..., an ( - 109 ≤ ai ≤ 109) — elements of the sequence.

Output

Output a single number — the number of ways to choose a subsequence of length three, such that it forms a geometric progression with a common ratio k.

Sample test(s)
Input
5 2
1 1 2 2 4
Output
4
Input
3 1
1 1 1
Output
1
Input
10 3
1 2 6 2 3 6 9 18 3 9
Output
6
Note

In the first sample test the answer is four, as any of the two 1s can be chosen as the first element, the second element can be any of the 2s, and the third element of the subsequence must be equal to 4.

题意:给一个长度为N的数列,和公比K,问此数列中可以找出多少个三元组形成公比为K的等比数列。

分析:枚举第二个数X,用两个map分别维护其左边X/K的个数和右边X*K的个数即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 200010;
map<LL,LL>mp1,mp2;
LL a[N];
int main()
{
    int i,j,n;
    LL k;
    while(scanf("%d %I64d",&n, &k) == 2)
    {
        LL ans = 0;
        mp1.clear(), mp2.clear();
        for(i=1; i<=n; i++)
            scanf("%I64d", a+i),
            mp2[a[i]]++;
        mp2[a[1]]--;
        for(i=2; i<n; i++)
        {
            mp1[a[i-1]]++;
            mp2[a[i]]--;
            if(a[i]%k) continue;
            ans += mp1[a[i]/k] * mp2[a[i]*k];
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

D. One-Dimensional Battle Ships
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Alice and Bob love playing one-dimensional battle ships. They play on the field in the form of a line consisting of n square cells (that is, on a 1 × n table).

At the beginning of the game Alice puts k ships on the field without telling their positions to Bob. Each ship looks as a 1 × a rectangle (that is, it occupies a sequence of a consecutive squares of the field). The ships cannot intersect and even touch each other.

After that Bob makes a sequence of "shots". He names cells of the field and Alice either says that the cell is empty ("miss"), or that the cell belongs to some ship ("hit").

But here's the problem! Alice like to cheat. May be that is why she responds to each Bob's move with a "miss".

Help Bob catch Alice cheating — find Bob's first move, such that after it you can be sure that Alice cheated.

Input

The first line of the input contains three integers: n, k and a (1 ≤ n, k, a ≤ 2·105) — the size of the field, the number of the ships and the size of each ship. It is guaranteed that the n, k and a are such that you can put k ships of size a on the field, so that no two ships intersect or touch each other.

The second line contains integer m (1 ≤ m ≤ n) — the number of Bob's moves.

The third line contains m distinct integers x1, x2, ..., xm, where xi is the number of the cell where Bob made the i-th shot. The cells are numbered from left to right from 1 to n.

Output

Print a single integer — the number of such Bob's first move, after which you can be sure that Alice lied. Bob's moves are numbered from 1 to m in the order the were made. If the sought move doesn't exist, then print "-1".

Sample test(s)
Input
11 3 3
5
4 8 6 1 11
Output
3
Input
5 1 3
2
1 5
Output
-1
Input
5 1 3
1
3
Output
1

题意:在一个1*N的格子上放置了K个1*a的矩形,且这些矩形不能邻接。现在依次给M个位置,表示这个位置不能放置矩形,问你当给出第几个位置时就不能放置K个了。

分析:可以先预处理每个长度可以放置矩形的个数,维护可以放置的区间,维护可放置的总数即可。

#include<bits/stdc++.h>
using namespace std;
set<int> st;
set<int>::iterator it;
int num[300000];
int d[300000];
int main()
{
    int i,j,k,m,n,a;
    while(scanf("%d %d %d",&n,&k,&a) == 3)
    {
        st.clear();
        num[0] = 0;
        for(i=1; i<=n; i++)
        {
            num[i] = i/(a+1);
            if(i%(a+1) == a) num[i]++;
           // printf("num[%d] = %d\n",i,num[i]);
        }
        scanf("%d",&m);
        st.insert(0);
        st.insert(n+1);
        int tp = num[n];
        for(i=1; i<=m; i++) scanf("%d",d+i);
        bool ok = false;
        for(i=1; i<=m; i++)
        {
            it = st.lower_bound(d[i]);
            it--;
            int a = *it;
            it++;
            int b = *it;
            tp -= num[b-a-1];
            tp += num[d[i]-a-1];
            tp += num[b-d[i]-1];
            if(tp < k) {
                printf("%d\n",i);
                ok = true;
                break;
            }
            st.insert(d[i]);
        }
        if(!ok) puts("-1");
    }
    return 0;
}

E. President and Roads
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Berland has n cities, the capital is located in city s, and the historic home town of the President is in city t (s ≠ t). The cities are connected by one-way roads, the travel time for each of the road is a positive integer.

Once a year the President visited his historic home town t, for which his motorcade passes along some path from s to t (he always returns on a personal plane). Since the president is a very busy man, he always chooses the path from s to t, along which he will travel the fastest.

The ministry of Roads and Railways wants to learn for each of the road: whether the President will definitely pass through it during his travels, and if not, whether it is possible to repair it so that it would definitely be included in the shortest path from the capital to the historic home town of the President. Obviously, the road can not be repaired so that the travel time on it was less than one. The ministry of Berland, like any other, is interested in maintaining the budget, so it wants to know the minimum cost of repairing the road. Also, it is very fond of accuracy, so it repairs the roads so that the travel time on them is always a positive integer.

Input

The first lines contain four integers n, m, s and t (2 ≤ n ≤ 105; 1 ≤ m ≤ 105; 1 ≤ s, t ≤ n) — the number of cities and roads in Berland, the numbers of the capital and of the Presidents' home town (s ≠ t).

Next m lines contain the roads. Each road is given as a group of three integers ai, bi, li (1 ≤ ai, bi ≤ nai ≠ bi; 1 ≤ li ≤ 106) — the cities that are connected by the i-th road and the time needed to ride along it. The road is directed from city ai to city bi.

The cities are numbered from 1 to n. Each pair of cities can have multiple roads between them. It is guaranteed that there is a path from s to t along the roads.

Output

Print m lines. The i-th line should contain information about the i-th road (the roads are numbered in the order of appearance in the input).

If the president will definitely ride along it during his travels, the line must contain a single word "YES" (without the quotes).

Otherwise, if the i-th road can be repaired so that the travel time on it remains positive and then president will definitely ride along it, print space-separated word "CAN" (without the quotes), and the minimum cost of repairing.

If we can't make the road be such that president will definitely ride along it, print "NO" (without the quotes).

Sample test(s)
Input
6 7 1 6
1 2 2
1 3 10
2 3 7
2 4 8
3 5 3
4 5 2
5 6 1
Output
YES
CAN 2
CAN 1
CAN 1
CAN 1
CAN 1
YES
Input
3 3 1 3
1 2 10
2 3 10
1 3 100
Output
YES
YES
CAN 81
Input
2 2 1 2
1 2 1
1 2 2
Output
YES
NO
Note

The cost of repairing the road is the difference between the time needed to ride along it before and after the repairing.

In the first sample president initially may choose one of the two following ways for a ride: 1 → 2 → 4 → 5 → 6 or 1 → 2 → 3 → 5 → 6.

题意:给一个有向图,现要从S到达T,对于每条边,如果一定会经过此边输出YES,否则能否减去一些权值使得他一定会被经过,如果能,输出应该减少的权值,否则输出NO。

分析:先求出各个点分别到S点和T点的最短路,对于S->T可以经过的边构无向图,那么一定会经过的边就是割边了。对于其余边,如果要使经过他,那么其边权值+一边到S的距离+一边到T的距离=S-T最短距离-1, 然后判断是否可以通过修改边权使之满足。注意:边权不能为0。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 100100;
const LL INF = 1LL<<50;
struct EG{
    int u,v;
    LL w;
    EG(int u=0, int v=0, LL w=0):u(u),v(v),w(w){}
}e[N];

bool ans[N];

/*****************最短路************************/
typedef pair<LL, int> pii;
LL d[2][N];
int first[N], Next[N], V[N];
LL W[N];
bool vis[N];
priority_queue<pii, vector<pii>, greater<pii> >P;
void SP(int s, int n, int a)
{
    memset(vis,0,sizeof(vis));
    for(int i=1; i<=n; i++) d[a][i] = i==s ? 0 : INF;
    while(!P.empty()) P.pop();
    P.push(make_pair(0,s));
    while(!P.empty())
    {
        pair<LL, int> u = P.top(); P.pop();
        int x = u.second;
        if(vis[x]) continue;
        vis[x]  = 1;
        for(int i=first[x]; i!=-1; i=Next[i])
        {
            int v = V[i];
            if(d[a][v] > d[a][x] + W[i]) {
                d[a][v] = d[a][x] + W[i];
                P.push(make_pair(d[a][v],v));
            }
        }
    }
}
void cal(int n, int m, int s, int t)
{
    int p = 0;
    memset(first, -1, sizeof(first));
    for(int i=1; i<=m; i++) {
        int u = e[i].u, v = e[i].v;
        LL w = e[i].w;
        V[++p]=v, Next[p]=first[u], first[u]=p, W[p]=w;
    }
    SP(s,n,0);
    p = 0;
    memset(first, -1, sizeof(first));
    for(int i=1; i<=m; i++) {
        int u = e[i].u, v = e[i].v;
        LL w = e[i].w;
        V[++p]=u, Next[p]=first[v], first[v]=p, W[p]=w;
    }
    SP(t,n,1);
}
/*********************************************************/


/***************找割边**********************************/
vector<pii>G[N];
int low[N], dfn[N];
int tim;
void tarjan(int u, int fa)
{
    vis[u] = 1;
    low[u] = dfn[u] = ++tim;
    for(int i=0; i<G[u].size(); i++)
    {
        pii p = G[u][i];
        int v = p.first;
        if(!vis[v]) {
            tarjan(v, p.second);
            low[u] = min(low[u], low[v]);
        }
        else if(p.second != fa)
            low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u] && fa) ans[fa] = 1;
}
void Search(int n, int m, int s, int t)
{
    for(int i=1; i<=n; i++) G[i].clear();
    memset(ans, 0, sizeof(ans));
    for(int i=1; i<=m; i++) {
        int u = e[i].u, v = e[i].v;
        if(d[0][t] == d[0][u]+d[1][v]+e[i].w)
            G[u].push_back(make_pair(v,i)),
            G[v].push_back(make_pair(u,i));
    }
    tim = 0;
    memset(vis,0,sizeof(vis));
    for(int i=1; i<=n; i++)
        if(!vis[i]) tarjan(i,0);
}
int main()
{
    int i,j,k,m,n,s,t;
    while(scanf("%d %d %d %d",&n,&m,&s,&t) == 4)
    {
        for(i=1; i<=m; i++) {
            scanf("%d %d %I64d",&e[i].u,&e[i].v,&e[i].w);
        }
        cal(n,m,s,t);
        Search(n,m,s,t);
        LL mn = d[0][t];
        for(i=1; i<=m; i++) {
            if(ans[i]) { puts("YES"); continue;}//YES
            int u = e[i].u, v = e[i].v;
            if(d[0][u]+d[1][v] >= mn-1) puts("NO");//NO
            else
                printf("CAN %I64d\n",e[i].w-mn+1+d[0][u]+d[1][v]);
        }
    }
    return 0;
}

F. Mausoleum
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

King of Berland Berl IV has recently died. Hail Berl V! As a sign of the highest achievements of the deceased king the new king decided to build a mausoleum with Berl IV's body on the main square of the capital.

The mausoleum will be constructed from 2n blocks, each of them has the shape of a cuboid. Each block has the bottom base of a 1 × 1 meter square. Among the blocks, exactly two of them have the height of one meter, exactly two have the height of two meters, ..., exactly two have the height of n meters.

The blocks are arranged in a row without spacing one after the other. Of course, not every arrangement of blocks has the form of a mausoleum. In order to make the given arrangement in the form of the mausoleum, it is necessary that when you pass along the mausoleum, from one end to the other, the heights of the blocks first were non-decreasing (i.e., increasing or remained the same), and then — non-increasing (decrease or remained unchanged). It is possible that any of these two areas will be omitted. For example, the following sequences of block height meet this requirement:

  • [1, 2, 2, 3, 4, 4, 3, 1];
  • [1, 1];
  • [2, 2, 1, 1];
  • [1, 2, 3, 3, 2, 1].

Suddenly, k more requirements appeared. Each of the requirements has the form: "h[xi] signi h[yi]", where h[t] is the height of the t-th block, and a signi is one of the five possible signs: '=' (equals), '<' (less than), '>' (more than), '<=' (less than or equals), '>=' (more than or equals). Thus, each of the k additional requirements is given by a pair of indexes xi, yi (1 ≤ xi, yi ≤ 2n) and sign signi.

Find the number of possible ways to rearrange the blocks so that both the requirement about the shape of the mausoleum (see paragraph 3) and the k additional requirements were met.

Input

The first line of the input contains integers n and k (1 ≤ n ≤ 35, 0 ≤ k ≤ 100) — the number of pairs of blocks and the number of additional requirements.

Next k lines contain listed additional requirements, one per line in the format "xi signi yi" (1 ≤ xi, yi ≤ 2n), and the sign is on of the list of the five possible signs.

Output

Print the sought number of ways.

Sample test(s)
Input
3 0
Output
9
Input
3 1
2 > 3
Output
1
Input
4 1
3 = 6
Output
3

题意:给你一个数集{1,1,2,2,3,3,4,4,......,n,n}, 问你有多少个排列满足先增后减, 增减都是不严格的,且要满足M条规则,规则指明了两个位置的大小关系。

分析:如果没有规则,我们可以按数字从小到大每次随意放两端即可,加了规则之后,只需在每一步后判断所放位置的合法性即可。我们初始答案序列为很大的数,因为没有放上去的位置一定会放一个比当前数大的数。

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int INF = 1<<20;
const int N = 80;
LL dp[N][N];
vector<int>lse[N],ls[N],eq[N],bge[N],bg[N];
int ans[N];
bool check(int a, int b, int now)
{
    ans[a] = ans[b] = now;
    int s[2] = {a, b};
    for(int i=0; i<2; i++)
    {
        int x = s[i];
        for(int j=0; j<ls[x].size(); j++)
            if(ans[x] >= ans[ls[x][j]]) {ans[a] = ans[b] = INF; return false;}
        for(int j=0; j<lse[x].size(); j++)
            if(ans[x] > ans[lse[x][j]]) {ans[a] = ans[b] = INF; return false;}
        for(int j=0; j<bg[x].size(); j++)
            if(ans[x] <= ans[bg[x][j]]) {ans[a] = ans[b] = INF; return false;}
        for(int j=0; j<bge[x].size(); j++)
            if(ans[x] < ans[bge[x][j]]) {ans[a] = ans[b] = INF; return false;}
        for(int j=0; j<eq[x].size(); j++)
            if(ans[x] != ans[eq[x][j]]) {ans[a] = ans[b] = INF; return false;}
    }
    return true;
}
LL DP(int x, int y, int now)
{
    if(x > y) return 1;
    if(dp[x][y] != -1) return dp[x][y];
    LL ret = 0;
    if(check(x, x+1, now)) ret += DP(x+2, y, now+1), ans[x] = ans[x+1] = INF;
    if(x + 1 != y) {
        if(check(x, y, now)) ret += DP(x+1, y-1, now+1), ans[x] = ans[y] = INF;
        if(check(y-1, y, now)) ret += DP(x, y-2, now+1), ans[y-1] = ans[y] = INF;
    }
    return dp[x][y] = ret;
}
int main()
{
    int i,j,k,m,n;
    char s[3];
    int a,b;
    while(scanf("%d%d",&n,&m) == 2)
    {
        for(i=1; i<=n*2; i++)
            lse[i].clear(), ls[i].clear(), eq[i].clear(),
            bge[i].clear(), bg[i].clear();
        while(m--)
        {
            scanf("%d %s %d",&a,s,&b);
            if(s[0] == '=') eq[a].push_back(b), eq[b].push_back(a);
            else if(s[0]=='>'&&s[1]=='=') bge[a].push_back(b), lse[b].push_back(a);
            else if(s[0]=='<'&&s[1]=='=') lse[a].push_back(b), bge[b].push_back(a);
            else if(s[0]=='>') bg[a].push_back(b), ls[b].push_back(a);
            else ls[a].push_back(b), bg[b].push_back(a);
        }
        memset(dp,-1,sizeof(dp));
        for(i=1; i<=n*2; i++) ans[i] = INF;
        printf("%I64d\n",DP(1,n*2,1));
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值