Codeforces Round #736 (Div. 2)(A~C)

Codeforces Round #736 (Div. 2)
A. Gregor and Cryptography(https://codeforces.com/contest/1549/problem/A)
Gregor is learning about RSA cryptography, and although he doesn’t understand how RSA works, he is now fascinated with prime numbers and factoring them.

Gregor’s favorite prime number is P. Gregor wants to find two bases of P. Formally, Gregor is looking for two integers a and b which satisfy both of the following properties.

Pmoda=Pmodb, where xmody denotes the remainder when x is divided by y, and
2≤a<b≤P.
Help Gregor find two bases of his favorite prime number!

Input
Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤1000).

Each subsequent line contains the integer P (5≤P≤109), with P guaranteed to be prime.

Output
Your output should consist of t lines. Each line should consist of two integers a and b (2≤a<b≤P). If there are multiple possible solutions, print any.

Example
inputCopy
2
17
5
outputCopy
3 5
2 4
Note
The first query is P=17. a=3 and b=5 are valid bases in this case, because 17mod3=17mod5=2. There are other pairs which work as well.

In the second query, with P=5, the only solution is a=2 and b=4.
题意:给定一个素数p,找到a,b满足p mod a=p mod b;
由于p>=5且p是一个素数,故p肯定是一个奇数,模2结果是1,并且对任意一个p,p模p-1结果也是1,故2,p-1即我们所求的解

AC代码:

#include <bits/stdc++.h>
using namespace std;
#define reset(x) memset(x, 0, sizeof(x))
#define Q_in_out                 \
    ios::sync_with_stdio(false); \
    cin.tie(0);                  \
    cout.tie(0);
typedef long long int ll;
typedef long double ld;
typedef pair<int, int> P;
#define forl(l,r) for(int i=l;i<r;i++) 
#define forr(r,l) for(int i=r;i>=l;i--)
const int N = 1e5+5;
const int modp = 1e9+7;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
const double pi = acos(-1.0);
const double e = 2.718281828459045;
int solve()
{
    int n;
    cin>>n;
    cout<<2<<' '<<n-1;
    return 0; 
}
int main()
{
    Q_in_out;
    int t;
    t = 1;
    cin >> t;
    while (t--)
    {
        solve();
        cout<<endl;
    }
    return 0;
}

B. Gregor and the Pawn Game(https://codeforces.com/contest/1549/problem/B)
There is a chessboard of size n by n. The square in the i-th row from top and j-th column from the left is labelled (i,j).

Currently, Gregor has some pawns in the n-th row. There are also enemy pawns in the 1-st row. On one turn, Gregor moves one of his pawns. A pawn can move one square up (from (i,j) to (i−1,j)) if there is no pawn in the destination square. Additionally, a pawn can move one square diagonally up (from (i,j) to either (i−1,j−1) or (i−1,j+1)) if and only if there is an enemy pawn in that square. The enemy pawn is also removed.

Gregor wants to know what is the maximum number of his pawns that can reach row 1?

Note that only Gregor takes turns in this game, and the enemy pawns never move. Also, when Gregor’s pawn reaches row 1, it is stuck and cannot make any further moves.

Input
The first line of the input contains one integer t (1≤t≤2⋅104) — the number of test cases. Then t test cases follow.

Each test case consists of three lines. The first line contains a single integer n (2≤n≤2⋅105) — the size of the chessboard.

The second line consists of a string of binary digits of length n, where a 1 in the i-th position corresponds to an enemy pawn in the i-th cell from the left, and 0 corresponds to an empty cell.

The third line consists of a string of binary digits of length n, where a 1 in the i-th position corresponds to a Gregor’s pawn in the i-th cell from the left, and 0 corresponds to an empty cell.

It is guaranteed that the sum of n across all test cases is less than 2⋅105.

Output
For each test case, print one integer: the maximum number of Gregor’s pawns which can reach the 1-st row.

Example
inputCopy
4
3
000
111
4
1111
1111
3
010
010
5
11001
00000
outputCopy
3
4
0
0
Note
In the first example, Gregor can simply advance all 3 of his pawns forward. Thus, the answer is 3.

In the second example, Gregor can guarantee that all 4 of his pawns reach the enemy row, by following the colored paths as demonstrated in the diagram below. Remember, only Gregor takes turns in this “game”!

In the third example, Gregor’s only pawn is stuck behind the enemy pawn, and cannot reach the end.

In the fourth example, Gregor has no pawns, so the answer is clearly 0.
题意:n*n棋盘第一行给出棋子情况,0代表空,1代表有棋子,同样规则给出另一行棋子,如果上一行同一列没棋子则,棋子可以往上移动一步
如果棋子的左上方或者右上方有一颗棋子,则该棋子可以往左上方或者右上方移动一步,问最终第一行最多可以有多少棋子


如果某个位置是0,那他下方的棋子一定会走上来,这样能保证最终棋子数量最多(如果不走这步,这个空格会被浪费),如果是1先检查左下方
是否有棋子,有则左下方棋子跳上来,若没有再检查右下方的棋子,这样能保证左边的棋子先跳到第一行,避免最左端棋子无法跳到最右端
AC代码:

#include <bits/stdc++.h>
using namespace std;
#define reset(x) memset(x, 0, sizeof(x))
#define Q_in_out                 \
    ios::sync_with_stdio(false); \
    cin.tie(0);                  \
    cout.tie(0);
typedef long long int ll;
typedef long double ld;
typedef pair<int, int> P;
#define forl(l,r) for(int i=l;i<r;i++) 
#define forr(r,l) for(int i=r;i>=l;i--)
const int N = 2e5+5;
const int modp = 1e9+7;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
const double pi = acos(-1.0);
const double e = 2.718281828459045;
bool vis[N];
int solve()
{
    int n;
    cin>>n;
    reset(vis);
    string se,sg;
    cin>>se;
    cin>>sg;
    int cnt=0;
    int l=0;
    for(int i=0;i<n;i++){
        if(se[i]=='0'){
            if(sg[i]=='1'&&vis[i]==0) {
                cnt++;
                vis[i]=1;
            }
        }
        else{
                if(i-1>=0&&vis[i-1]==0&&sg[i-1]=='1'){
                    cnt++;
                    vis[i-1]=1;
                    continue;
                }
                if(i+1<n&&vis[i+1]==0&&sg[i+1]=='1'){
                    cnt++;
                    vis[i+1] =1;
                    continue;
                }
        }
    }
    cout<<cnt;
    return 0; 
}
int main()
{
    Q_in_out;
    int t;
    t = 1;
    cin >> t;
    while (t--)
    {
        solve();
        cout<<endl;
    }
    return 0;
}

C. Web of Lies(https://codeforces.com/contest/1549/problem/C)
Cersei Lannister, A Game of Thrones by George R. R. Martin
There are n nobles, numbered from 1 to n. Noble i has a power of i. There are also m “friendships”. A friendship between nobles a and b is always mutual.

A noble is defined to be vulnerable if both of the following conditions are satisfied:

the noble has at least one friend, and
all of that noble’s friends have a higher power.
You will have to process the following three types of queries.

Add a friendship between nobles u and v.
Remove a friendship between nobles u and v.
Calculate the answer to the following process.
The process: all vulnerable nobles are simultaneously killed, and all their friendships end. Then, it is possible that new nobles become vulnerable. The process repeats itself until no nobles are vulnerable. It can be proven that the process will end in finite time. After the process is complete, you need to calculate the number of remaining nobles.

Note that the results of the process are not carried over between queries, that is, every process starts with all nobles being alive!

Input
The first line contains the integers n and m (1≤n≤2⋅105, 0≤m≤2⋅105) — the number of nobles and number of original friendships respectively.

The next m lines each contain the integers u and v (1≤u,v≤n, u≠v), describing a friendship. No friendship is listed twice.

The next line contains the integer q (1≤q≤2⋅105) — the number of queries.

The next q lines contain the queries themselves, each query has one of the following three formats.

1 u v (1≤u,v≤n, u≠v) — add a friendship between u and v. It is guaranteed that u and v are not friends at this moment.
2 u v (1≤u,v≤n, u≠v) — remove a friendship between u and v. It is guaranteed that u and v are friends at this moment.
3 — print the answer to the process described in the statement.
Output
For each type 3 query print one integer to a new line. It is guaranteed that there will be at least one type 3 query.

Examples
inputCopy
4 3
2 1
1 3
3 4
4
3
1 2 3
2 3 1
3
outputCopy
2
1
inputCopy
4 3
2 3
3 4
4 1
1
3
outputCopy
1
Note
Consider the first example. In the first type 3 query, we have the diagram below.

In the first round of the process, noble 1 is weaker than all of his friends (2 and 3), and is thus killed. No other noble is vulnerable in round 1. In round 2, noble 3 is weaker than his only friend, noble 4, and is therefore killed. At this point, the process ends, and the answer is 2.

In the second type 3 query, the only surviving noble is 4.

The second example consists of only one type 3 query. In the first round, two nobles are killed, and in the second round, one noble is killed. The final answer is 1, since only one noble survives.

题意:初始n个节点,序号1~n,给出m个关系,Q次查询,若查询是3,输出操作后剩余人数,若查询是1,则输入两个数uv,代表给uv添加边若查询是2,则输入两个数uv,代表删除uv这条边。
上述的操作指:从序号最小开始检查,若其至少和一个序号大于自己的节点有边,则把该点删掉,同时所有与这个被删掉的节点有关的边都会被删掉,重复操作,直至找不到这样的节点为止。

根据题意,我们在添加边时只需要给序号小的节点添加标记,因为该节点一定满足操作的要求,一定会被删掉,利用map记录每个节点的边数即可,需要注意的是,每次查询3结束后,删掉的节点会被恢复,也即是要从删之前的状态开始执行下一次查询
AC代码:

#include <bits/stdc++.h>
using namespace std;
#define reset(x) memset(x, 0, sizeof(x))
#define Q_in_out                 \
    ios::sync_with_stdio(false); \
    cin.tie(0);                  \
    cout.tie(0);
typedef long long int ll;
typedef long double ld;
typedef pair<int, int> P;
#define forl(l,r) for(int i=l;i<r;i++) 
#define forr(r,l) for(int i=r;i>=l;i--)
const int N = 2e5+5;
const int modp = 1e9+7;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
const double pi = acos(-1.0);
const double e = 2.718281828459045;
unordered_map<int,int>res,tmp;
int solve()
{
    int n,m,a,b,c;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>a>>b;
        res[min(a,b)]++;
    }
    int q;
    cin>>q;
    if(n==1&&m==0){
        while (q--)
        {
            cin>>a;
            if(a==3) cout<<1<<endl;
            else{
                cin>>b>>c;
            }
        }
        return 0;
    }

    tmp=res;
    while (q--)
    {
        cin>>a;
        if(a==3){
            cout<<n-tmp.size()<<endl;
            // tmp.clear();
            // tmp=res;
        }
        else if(a==1){
            cin>>b>>c;
            tmp[min(b,c)]++;
        }
        else{
            cin>>b>>c;
            int xp=min(b,c);
            tmp[xp]--;
            if(tmp[xp]==0) tmp.erase(xp);
        }
    }
    
    return 0; 
}
int main()
{
    Q_in_out;
    int t;
    t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
        cout<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值