EOJ Monthly 2021.9

比赛链接

EOJ Monthly 2021.9 Sponsored by TuSimple


A. Amazing Discovery

单点时限: 1.0 sec

内存限制: 1024 MB

题目描述

Siyu recently made an amazing discovery. If \(a,b,n\) are all positive integers, then

\[S=(a+\sqrt{b})^n+(a-\sqrt{b})^n \]

is also a positive integer.

To verify his discovery, please print \(S\) modulo 998244353.

输入格式

The only line contains three integers \(a,b\) and \(n (1 \leq a,b,n \leq 10^9)\).

输出格式

Print on a line \(S\) modulo 998244353.

样例

input

1 2 3

output

14

解题思路

分治,记忆化

我们可以推导出这样的式子:
image
为防止不必要的重复计算,我们可以记忆化
这里需要额外注意的一点是,快速幂的底数可能为负数,需要转换一下~

  • 时间复杂度:\(O(logn)\)

代码

#include<bits/stdc++.h>
using namespace std;
using LL=long long;
const LL mod=998244353;
unordered_map<int,LL>mp;
LL ksm(LL a,int b)
{
    a=(a%mod+mod)%mod;
    LL res=1%mod;
    for(;b;b>>=1)
    {
        if(b&1)res=res*a%mod;
        a=a*a%mod;
    }
    return res;
}
LL a;
int b,n;
LL cal(int n)
{
    if(mp.find(n)!=mp.end())return mp[n];
    if(n==0)return 2;
    if(n==1)return 2*a;
    if(n&1)
    {
        int x=n/2,y=n-x;
        return mp[n]=(cal(x)*cal(y)%mod-2*a%mod*ksm(a*a-b,x)%mod+mod)%mod;
    }
    LL tmp=cal(n/2);
    return mp[n]=(tmp*tmp%mod-2*ksm(a*a-b,n/2)%mod+mod)%mod;
}
int main()
{
    scanf("%d%d%d",&a,&b,&n);
    printf("%lld",cal(n));
    return 0;
}

B. Mine sweeper

单点时限: 1.0 sec

内存限制: 256 MB

题目描述

Now, little w is playing the game Mine-sweeper. The game is working on a \(n\times m\) grid field and each cell contains 0 or 1 mine.

For each cell, little w only know the total number of mines in itself and its 8 adjacent cells. He wants to know the total number of mines in this field, please help him.

输入格式

The first line contains two positive integers \(n\) and \(m\). \((1\leq n,m \leq 200)\)

In the following \(n\) lines, each line contains \(m\) integers. And each number represents the information little w knows of a cell, the total number of mines in itself and its 8 adjacent cells.

输出格式

One line with one integer represents the total number of mines.

input

3 4
2 3 2 1
2 3 2 1
1 2 2 1

output

3

input

4 5
1 1 3 3 3
1 2 5 5 4
0 1 4 5 4
0 1 3 4 3

output

8

提示

For example, suppose the number of mine in a field likes

011
010
000
Then little w will know

233
233
111

解题思路

题目只要求总的地雷数,我们可以根据周围地雷的总个数进行求解,即上下左右间隔3个格子,如:

image

我们发现:开始选择位置时需要保证不能出现单行,这样无法求解,所以需要分情况讨论(只用确定第一个位置 \((x,y)\) 就行,甚至我们发现行列之间是相互独立的~):

  • \(n\%3=0/2\) 时,\(x=1\);
    \(m\%3=0/2\) 时,\(y=1\)
  • \(n\%3=1\) 时,\(x=0\);
    \(m\%3=1\) 时,\(y=0\)
  • 时间复杂度:\(O(nm)\)

代码

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[210][210];
int main()
{
    int res=0;
    cin>>n>>m;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>a[i][j];
    int x=n%3==1?0:1,y=m%3==1?0:1;
    for(int i=x;i<n;i+=3)
        for(int j=y;j<m;j+=3)
            res+=a[i][j];
    cout<<res;
    return 0;
}

C. Connection

题目描述

单点时限: 1.0 sec

内存限制: 256 MB

Now, little W gets a 01 matrix of size \(N\times M\). He wants to turn all elements in the matrix to 1. He can do the following operations:

  1. Turning any one element to 1 from 0 costs 4.

  2. If positions \((x_1,y_1),(x_2,y_1)\) and \((x_1,y_2)\) are 1, turning \((x_2,y_2)\) to 1 from 0 will cost 3.

He wants to know the minimum cost, please help him.

输入格式

The first line contains two positive integers \(N\) and \(M\).

The following \(N\) lines represent the matrix with only 0 and 1.

输出格式

The answer.

input

2 5
10010
00001

output

24

input

6 6
010000
011010
110111
100101
110001
110100

output

54

解题思路

要使花费最少,即使得操作1的次数最少,不妨将行和列分开,即:
把行和列看作点,共 \(n+m\) 个点,\(matrix(x,y)=1\) 则把 \(x\)\(y\) 连边,这样一个连通块内的点连边的话都可以通过操作2得到,我们要使整个不同连通块连成一个连通块才能使花费最少,操作1的目的就是使不同连通块连一起

  • 时间复杂度:\(O(n+m+nm)\)

代码

#include<bits/stdc++.h>
using namespace std;
int n,m;
int cnt0;//0的数量
int cnt;//连通块的数量
string s[1010];
vector<int> adj[2010];
int v[2010];//标记哪个点属于哪个连通块
void dfs(int x)
{
    v[x]=cnt;
    for(int y:adj[x])
    {
        if(v[y])continue;
        dfs(y);
    }
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        cin>>s[i];
        for(int j=0;j<m;j++)
            if(s[i][j]=='1')
            {
                adj[i].push_back(j+n);
                adj[j+n].push_back(i);
            }
            else
                cnt0++;
    }
    int res=3*cnt0;
    for(int i=0;i<n+m;i++)
    {
        if(!v[i])
        {
            cnt++;
            dfs(i);
        }

    }
    cout<<res+cnt-1;
    return 0;
}

D. Divide and Merge

单点时限: 1.0 sec

内存限制: 1024 MB

题目描述

Alice and Bob are playing a game about stones.
There are piles of stones, the \(i\)-th pile of which initially contains \(a_i\) stones.

They take turns to perform one of the following operations, starting from Alice.

  • Split one pile of stones of odd number into two piles. Neither of the two split piles can be empty.
  • Merge two piles of stones of even number into one pile.
    The one who cannot perform any operation lose the game.

Suppose Alice and Bob play the game optimally, do you know who will win the game?

输入格式

The first line contains an integer \(n (1\leq n \leq 10^4)\).

The second line contains \(n\) integers \(a_1,…,a_n (1 \leq a_1,…,a_n \leq 10 ^5)\).

输出格式

Print Alice or Bob, the winner of the game.

样例

input

10
14270 15338 11437 8641 28379 15164 20738 7458 21978 17434

output

Bob

input

4
1 1 1 1

output

Bob

提示

The second line of the input of the first example is wrapped due to the limited space. All ten numbers are on a single line in the real input file.

解题思路

image

\(\color{red}{不考虑特殊情况,为什么偶数必胜?}\)
每次进行操作,某人偶数堆奇偶性不变,而最终偶数堆的数量肯定是要减少的,减少到1时必败,如果某人偶数堆为偶数,则不会到此必败点

  • 时间复杂度:\(O(1)\)

代码

#include<bits/stdc++.h>
using namespace std;
int x,even,n,num1;
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>x;
        if(!(x&1))even++;
        if(x==1)num1++;
    }
    puts((num1==n||(even&1))?"Bob":"Alice");
    return 0;
}

E. Effective Gradient

单点时限: 2.0 sec

内存限制: 256 MB

题目描述

Little W likes rational number \(\frac{P}{Q}\) very much. He has n points on the plane. You need to tell him the closest gradient to \(\frac{P}{Q}\) of the lines passing through at least two points.

Suppose a line passes through two points \((x_0,y_0)\) and \((x_1,y_1)\). The gradient of it is exactly \(g=\frac{y_0-y_1}{x_0-x_1}\). Closest gradient means

\[{\underset {g \in G}{\operatorname {arg\,min} }}\,\left | g-\frac{P}{Q} \right | \]

as is the set of gradients of all availible lines.

输入格式

The first lines contain three integers \(n,P,Q.(5 \leq n \leq 10^6,1 \leq P,Q \leq 10^5)\)

In the following \(n\) lines, each line contains two integers \(x,y\) represent the coordinate of a point.\(1 \leq x,y \leq 10^9\)

输出格式

You should output a rational number \(P'/Q'\) represents the answer.

We ensure that the answer is unique and larger than 0.

You can use 1/0 to represent the gradient of infinity.

input

6 15698 17433
112412868 636515040
122123982 526131695
58758943 343718480
447544052 640491230
162809501 315494932
870543506 895723090

output

193409386/235911335

解题思路

LCP 37. 最小矩形面积有类似的思路,即:
预处理:按点沿 \(P/Q\) 方向上的投影排序,相当于重新确定点的位置

结论:答案一定出现在相邻点

\(\color{red}{为什么?}\)
image

反证法:我们假设紫色线为我们的答案,如果两根线中间还存在其他点的话,无论该点在紫色线上面还是下面,总存在一条包含该点的直线要比答案更优,有当前答案矛盾,故中间不可能存在其他点;答案斜率 \(>0\) 时同理
注意:为求方便计算,我们可将整数类型转换为 double,double 有效位 15 位足够了~

  • 时间复杂度:\(O(nlogn)\)

代码

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
//y=k*x+b,y0=k*x0+b;按b排序
pair<double,double> a[1000010];
double P,Q,k;
int n;
int main()
{
    scanf("%d%lf%lf",&n,&P,&Q);
    for(int i=1;i<=n;i++)scanf("%lf%lf",&a[i].fi,&a[i].se);
    k=P/Q;
    sort(a+1,a+1+n,[](auto &x,auto &y){if((x.se-k*x.fi)==(y.se-k*y.fi))return x.fi<y.fi;return (x.se-k*x.fi)>(y.se-k*y.fi);});
    int p=1,q=0;
    for(int i=1;i<n;i++)
        if(abs(1.0*p/q-k)>abs((a[i].se-a[i+1].se)/(a[i].fi-a[i+1].fi)-k))p=a[i+1].se-a[i].se,q=a[i+1].fi-a[i].fi;
    printf("%d/%d",p/__gcd(p,q),q/__gcd(p,q));
    return 0;
}

F. Frog

单点时限: 6.0 sec

内存限制: 1024 MB

题目描述

Mr Frog likes traveling, and once he came to a magical country. The country has \(n\) cities, connected with \(n-1\) bi-directional roads. Each city was assigned a level of beauty \(b\) by Mr Frog. Mr Frog had planned several travels in the country. For each plan, there was a fixed departure city \(s\) and a fixed destination city \(t\). He could choose several cities to explore in detail, but he would only choose the cities on the shortest path from \(s\) to \(t\) (including \(s\) and \(t\)). He favored the number \(k\), so he wanted to choose some cities so that the sum of the level of beauty of those cities can be divided by \(k\).

Mr Frog asked you for helping him calculate the number of different choices satisfying his requirement. Two choices are different if Mr Frog would visit one city in one choice but would not visit that city in another choice. For sake of convenience, just output the answer modulo \(998244353\).

输入格式

The first line contains two integers \(n\) and \(k (1 \leq n \leq 2\times 10^5,2 \leq k \leq 50)\).

Each of the next \(n-1\) lines contains two integers \(x\) and \(y (1 \leq x,y \leq n)\), indicating there is a road connecting the city \(x\) and \(y\).

The next line contains \(n\) integers \(b_1,\dots,b_n (0 \leq b_1,\dots,b_n < k)\), where \(b_i\) represents the level of beauty of city \(i\).

The next line contains an integer \(q (1 \leq q \leq 10^6)\), indicating the number of travel plans.

Each of the next lines contains two integer \(s\) and \(t (1 \leq s,t \leq n)\).

输出格式

For each plan, print on a line the number of different choices modulo \(998244353\).

input

5 2
1 2
2 3
3 4
4 5
1 0 1 0 1
3
1 3
2 4
1 5

output

4
4
16

解题思路

代码


posted @ 2021-09-13 23:08  zyy2001  阅读(41)  评论(0编辑  收藏  举报