Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)

C. Kuroni and Impossible Calculation
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
To become the king of Codeforces, Kuroni has to solve the following problem.

He is given n numbers a1,a2,…,an. Help Kuroni to calculate ∏1≤i<j≤n|ai−aj|. As result can be very big, output it modulo m.

If you are not familiar with short notation, ∏1≤i<j≤n|ai−aj| is equal to |a1−a2|⋅|a1−a3|⋅ … ⋅|a1−an|⋅|a2−a3|⋅|a2−a4|⋅ … ⋅|a2−an|⋅ … ⋅|an−1−an|. In other words, this is the product of |ai−aj| for all 1≤i<j≤n.

Input
The first line contains two integers n, m (2≤n≤2⋅105, 1≤m≤1000) — number of numbers and modulo.

The second line contains n integers a1,a2,…,an (0≤ai≤109).

Output
Output the single number — ∏1≤i<j≤n|ai−aj|modm.

Examples
inputCopy
2 10
8 5
outputCopy
3
inputCopy
3 12
1 4 5
outputCopy
0
inputCopy
3 7
1 4 9
outputCopy
1
Note
In the first sample, |8−5|=3≡3mod10.

In the second sample, |1−4|⋅|1−5|⋅|4−5|=3⋅4⋅1=12≡0mod12.

In the third sample, |1−4|⋅|1−9|⋅|4−9|=3⋅8⋅5=120≡1mod7.

题意:让你求在这里插入图片描述
含义是在这里插入图片描述
就是连乘 看数据范围暴力是肯定不行的 找规律然后找不出来 dp也更没得 正解其实是个暴力 但是是优化过数据范围的 用到鸽巢原理 也就是抽屉原理 以下内容摘自百度 桌上有十个苹果,要把这十个苹果放到九个抽屉里,无论怎样放,我们会发现至少会有一个抽屉里面放不少于两个苹果。这一现象就是我们所说的“抽屉原理”。 抽屉原理的一般含义为:“如果每个抽屉代表一个集合,每一个苹果就可以代表一个元素,假如有n+1个元素放到n个集合中去,其中必定有一个集合里至少有两个元素。

易得n > m的话 就一定存在 a %m == b%m 等价 (a - b)%m == 0 所以答案n > m答案一定是0
我们假设m = 4 n = 5 取模后的情况只有0 1 2 3 四种情况 无论最后一个数取什么值都会有重复出现 所以就会有 (a - b)%m == 0

所以当n <=m 时 m的范围只有1000 n*n暴力就好

#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define pb(x) push_back(x)
#define debug(x) cout<<"..........."<<x<<endl;
#define fi first
#define se second

const int N = 2e5+5;
const int M = 1e3+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;

int a[N];

int main()
{
    int n,m;

    cin >> n >> m;

    for(int i = 0;i < n;i ++)
        cin >> a[i];

    if(n > m)
    {
        cout << 0 << '\n';
        return 0;
    }

    LL sum = 1;

    for(int i = 0;i < n ;i ++)
    {
        for(int j = i + 1;j < n;j ++)
        {
            sum = (sum * abs(a[i] - a[j])) % m;
        }
    }

    cout << sum%m << '\n';

    return 0;
}


注意sum *= abs(x)%m 和 sum = sum * abs(x)%m 是完全不同的 前者是 乘取模后的数 后者才是乘完后取模

D. Kuroni and the Celebration
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
This is an interactive problem.

After getting AC after 13 Time Limit Exceeded verdicts on a geometry problem, Kuroni went to an Italian restaurant to celebrate this holy achievement. Unfortunately, the excess sauce disoriented him, and he’s now lost!

The United States of America can be modeled as a tree (why though) with n vertices. The tree is rooted at vertex r, wherein lies Kuroni’s hotel.

Kuroni has a phone app designed to help him in such emergency cases. To use the app, he has to input two vertices u and v, and it’ll return a vertex w, which is the lowest common ancestor of those two vertices.

However, since the phone’s battery has been almost drained out from live-streaming Kuroni’s celebration party, he could only use the app at most ⌊n2⌋ times. After that, the phone would die and there will be nothing left to help our dear friend! 😦

As the night is cold and dark, Kuroni needs to get back, so that he can reunite with his comfy bed and pillow(s). Can you help him figure out his hotel’s location?

Interaction
The interaction starts with reading a single integer n (2≤n≤1000), the number of vertices of the tree.

Then you will read n−1 lines, the i-th of them has two integers xi and yi (1≤xi,yi≤n, xi≠yi), denoting there is an edge connecting vertices xi and yi. It is guaranteed that the edges will form a tree.

Then you can make queries of type “? u v” (1≤u,v≤n) to find the lowest common ancestor of vertex u and v.

After the query, read the result w as an integer.

In case your query is invalid or you asked more than ⌊n2⌋ queries, the program will print −1 and will finish interaction. You will receive a Wrong answer verdict. Make sure to exit immediately to avoid getting other verdicts.

When you find out the vertex r, print “! r” and quit after that. This query does not count towards the ⌊n2⌋ limit.

Note that the tree is fixed beforehand and will not change during the queries, i.e. the interactor is not adaptive.

After printing any query do not forget to print end of line and flush the output. Otherwise, you might get Idleness limit exceeded. To do this, use:

fflush(stdout) or cout.flush() in C++;
System.out.flush() in Java;
flush(output) in Pascal;
stdout.flush() in Python;
see the documentation for other languages.
Hacks

To hack, use the following format:

The first line should contain two integers n and r (2≤n≤1000, 1≤r≤n), denoting the number of vertices and the vertex with Kuroni’s hotel.

The i-th of the next n−1 lines should contain two integers xi and yi (1≤xi,yi≤n) — denoting there is an edge connecting vertex xi and yi.

The edges presented should form a tree.

Example
inputCopy
6
1 4
4 2
5 3
6 3
2 3

3

4

4

outputCopy

? 5 6

? 3 1

? 1 2

! 4
Note
Note that the example interaction contains extra empty lines so that it’s easier to read. The real interaction doesn’t contain any empty lines and you shouldn’t print any extra empty lines as well.

The image below demonstrates the tree in the sample test:

题意&思路:交互题 我也不知道啥意思 但是题是好的 每次给出两个点 询问两个点的lca是不是根节点
当两个点中有一个点是lca本身时 这个点肯定是根节点 如果不是就删掉这个点 从拓扑排序的角度来看 入度为1的点一定是叶子节点 我们从叶子节点开始删除 注意会产生新的叶子节点

#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define pb(x) push_back(x)
#define debug(x) cout<<"..........."<<x<<endl;
#define fi first
#define se second

const int N = 1e3 + 5;
const int M = 1e3+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;

vector <int> e[N];
int de[N];
int v[N];

int main()
{
    int n;

    cin >> n;

    int x,y;
///双向边 入度计算
    for(int i = 1;i < n;i ++)
    {
        cin >> x >> y ;
        e[x].push_back(y);
        e[y].push_back(x);
        de[x] ++;
        de[y] ++ ;
    }

    queue <int> que;

    for(int i = 1;i <= n;i ++)
    {
        if(de[i] == 1)
            que.push(i);///叶子节点进入
    }

    for(int i = 1;i <= n/2 ;i ++)
    {
        x = que.front();
        que.pop();

        y = que.front();
        que.pop();

        cout << "? " << x << " " << y << endl;///交互询问
        fflush(stdout);

        int z;

        cin >> z;

        if (z == x || z == y)///如果当前点的lca为自己本身则为根节点
        {
            cout << "! " << z << endl;
            return 0;
        }

        for (int z : e[x])///如果有未进入的叶子则让其入队列
            if (!v[z] && (--de[z] == 1)) que.push(z);
        for (int z : e[y])
            if (!v[z] && (--de[z] == 1)) que.push(z);

        v[x] = v[y] = 1;
    }

    for(int i = 1;i <= n;i ++)
    {
        if(!v[i])
            cout << "! " << i << '\n';
    }

    return 0;
}

E. Kuroni and the Score Distribution
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Kuroni is the coordinator of the next Mathforces round written by the “Proof by AC” team. All the preparation has been done, and he is discussing with the team about the score distribution for the round.

The round consists of n problems, numbered from 1 to n. The problems are ordered in increasing order of difficulty, no two problems have the same difficulty. A score distribution for the round can be denoted by an array a1,a2,…,an, where ai is the score of i-th problem.

Kuroni thinks that the score distribution should satisfy the following requirements:

The score of each problem should be a positive integer not exceeding 109.
A harder problem should grant a strictly higher score than an easier problem. In other words, 1≤a1<a2<⋯<an≤109.
The balance of the score distribution, defined as the number of triples (i,j,k) such that 1≤i<j<k≤n and ai+aj=ak, should be exactly m.
Help the team find a score distribution that satisfies Kuroni’s requirement. In case such a score distribution does not exist, output −1.

Input
The first and single line contains two integers n and m (1≤n≤5000, 0≤m≤109) — the number of problems and the required balance.

Output
If there is no solution, print a single integer −1.

Otherwise, print a line containing n integers a1,a2,…,an, representing a score distribution that satisfies all the requirements. If there are multiple answers, print any of them.

Examples
inputCopy
5 3
outputCopy
4 5 9 13 18
inputCopy
8 0
outputCopy
10 11 12 13 14 15 16 17
inputCopy
4 10
outputCopy
-1
Note
In the first example, there are 3 triples (i,j,k) that contribute to the balance of the score distribution.

(1,2,3)
(1,3,4)
(2,4,5)

题意:构造一个长度为n的序列 满足三元组 (i,j,k )1 < i < j < k < n 且 ai + aj = ak 数量为m 如果不存在的话就输出-1

思路:借鉴大佬的博客 从1 2 3 4 5 开始构造 发现m的数量会变成 0 0 1 2 4 且当三元组数量大于m时 差值为k 最后一个数 每大于二 会使得满足数量会减一 所以最后一位 +2k 则刚好为m个

#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define pb(x) push_back(x)
#define debug(x) cout<<"..........."<<x<<endl;
#define fi first
#define se second

const int N = 5e3 + 5;
const int M = 1e3+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;

int a[N];

int main()
{
    int n,m ;

    scanf("%d%d",&n,&m);

    int t = 0;

    for(int i = 0;i < n;i ++)
    {
        a[i] = i + 1;

        t += i / 2;

        if(t >= m)
        {
            a[i] += (t - m) << 1;

            int k = 1e9;

            for(int j = n - 1;j > i;j -- ,k = k - i  - 2)
                a[j] = k;

            for(int j = 0;j < n;j ++)
                printf("%d ",a[j]);

            return 0;
        }
    }

    printf("-1\n");

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值