“蔚来杯“2022牛客暑期多校训练营1

C Grab the Seat!

链接:https://ac.nowcoder.com/acm/contest/33186/C
来源:牛客网

时间限制:C/C++ 5秒,其他语言10秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

Oshwiciqwq studies Physics in a shabby classroom in his sophomore year. The classroom has nnn rows and mmm columns of seats, which are narrowly set like a matrix. There is a huge screen in the front of the classroom.

The whole classroom can be seen as a plane, and every seat can be seen as a point on it. The set of all seats’ coordinates is {(x,y)∣1≤x≤n,1≤y≤m,x∈Z+,y∈Z+}{(x,y) \mid 1 \le x\le n,1 \le y \le m,x\in \mathbb{Z}^+,y\in \mathbb{Z}^+}{(x,y)∣1≤x≤n,1≤y≤m,x∈Z+,y∈Z+}. Additionally, the screen can be seen as a segment, with two endpoints at (0,1)(0,1)(0,1) and (0,m)(0,m)(0,m).

As a student who loves studying, he always wants to seat in the front row, so that he can see the whole screen clearly. He thinks a seat is good if and only if there are no other people blocking him from seeing the whole screen. Formally, the seat at (a,b)(a,b)(a,b) is good if and only if there is no other person sitting on the seat that is on the segment between (a,b)(a,b)(a,b) and any point on the segment (0,1)−(0,m)(0,1)-(0,m)(0,1)−(0,m) (including endpoints).

However, today he arrived at the classroom as early as usual, only to find kkk people had already taken their seats. What’s worse, while he was busy searching for a good seat, some people changed their seats one by one. Totally there are qqq events of changing seats. He is extremely anxious now, so could you please help him count how many seats are good after each of the qqq changing events?

Obviously, a seat can only be occupied by at most one person at the same time.

输入描述:

The first line contains four integers n,m,k,qn,m,k,qn,m,k,q (2≤n,m≤2×105,1≤k≤2×105,1≤q≤2002 \le n,m \le 2\times 10^5,1 \le k \le 2\times 10^5,1 \le q \le 2002≤n,m≤2×105,1≤k≤2×105,1≤q≤200), denoting the number of rows, the number of columns, the number of people already taken seats and the number of changing events.

For the iii-th line in the following kkk lines, there are two integers xi,yix_i,y_ixi​,yi​ (1≤xi≤n,1≤yi≤m1 \le x_i \le n,1 \le y_i \le m1≤xi​≤n,1≤yi​≤m), denoting the coordinates of an occupied seat.

For the iii-th line in the following qqq lines, there are three integers pi,xi,yip_i,x_i,y_ipi​,xi​,yi​ (1≤pi≤k,1≤xi≤n,1≤yi≤m1 \le p_i \le k,1 \le x_i \le n,1 \le y_i \le m1≤pi​≤k,1≤xi​≤n,1≤yi​≤m), denoting the id of person changing seats and the coordinates of a seat that the person will change to.

It is guaranteed that any coordinate appears only once in the input.

输出描述:

The output contains qqq lines.

For each of the qqq changing events, print an integer in a single line, denoting the number of good seats at that time.

示例1

输入

7 6 6 1
3 1
4 2
4 5
6 3
6 5
6 2
6 6 1

输出

24

说明

The first sample is shown in the graph. The segment on the yyy-axis denotes the screen. The rectangular area denotes all the seats. After the changing event, the red points are the occupied seats while the green points are good seats.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vdPY9Ate-1658477061962)(https://uploadfiles.nowcoder.com/images/20220718/0_1658115296270/4A47A0DB6E60853DEDFCFDF08A5CA249)]

This is an example of a non-good seat. For the seat at (5,2)(5,2)(5,2), the segment between it and (0,2)(0,2)(0,2) on the screen contains a occupied seat at (4,2)(4,2)(4,2), so it is not a good seat.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yu2mqKex-1658477061963)(https://uploadfiles.nowcoder.com/images/20220718/0_1658115340614/FB5C81ED3A220004B71069645F112867)]

输入

10 10 5 5
4 10
5 9
4 2
6 5
4 7
3 3 5
2 4 1
3 3 6
2 10 6
5 7 4

输出

35
34
36
39
39

给你一块屏幕,问你有多少个位置没有被挡住,这里被挡住的定义是从屏幕的任意一个连线不会经过任何其他人

对于 y = 1 ∣ ∣ m y=1||m y=1∣∣m的行需要特判,因为他们会挡住后面的所有人

对于同行(即y)相等的情况下,如果 x 1 < x 2 x_1<x_2 x1<x2,那么第一个点的影响会大于第二个点,所以我们只用判定每一行最前面一个点即可
然后我们只需要维护一条相对于(0,1)和(0,m)来说斜率最大的两条直线,然后对于每一行按照斜率处理出每一行和该直线的交点前一个点,就是我们所求的答案

AC代码

/****************
 *@description:for the Escape Project
 *@author: Nebula_xuan
 * @Date: 2022-07-22 15:48:49
 *************************************************************************/

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
#define rep(i, h, t) for (int i = h; i <= t; i++)
#define dep(i, t, h) for (int i = t; i >= h; i--)
#define endl char(10)
#define int long long
//记得%d应该写成%lld

typedef pair<int, int> PII;
typedef long long ll;

const int N = 2e5 + 10;
int x[N], y[N], x1[N], mn[N];

signed main()
{
    ios::sync_with_stdio(false);
    int n, m, k, q;
    cin >> n >> m >> k >> q;
    rep(i, 1, k)
            cin >>
        x[i] >> y[i];
    rep(f, 1, q)
    {
        int id;
        cin >> id;
        cin >> x[id] >> y[id];
        rep(i, 1, m)
        {
            x1[i] = n + 1, mn[i] = n;
        }
        rep(i, 1, k)
            x1[y[i]] = min(x1[y[i]], x[i]);
        int j = 0;
        rep(i, 1, m)
        {
            if (x1[i] != n + 1 && (!j || x1[i] * (j - 1) - (i - 1) * x1[j] < 0))
                j = i;
            if (j == 1)
                mn[i] = min(mn[i], i == 1 ? x1[i] - 1 : n);
            else
                mn[i] = min(mn[i], j ? ((i - 1) * x1[j] - 1) / (j - 1) : n);
        }
        j = 0;
        dep(i, m, 1)
        {
            if (x1[i] != n + 1 && (!j || x1[i] * (j - m) - (i - m) * x1[j] > 0))
                j = i;
            if (j == m)
                mn[i] = min(mn[i], i == m ? x1[i] : n);
            else
                mn[i] = min(mn[i], j ? ((m - i) * x1[j] - 1) / (m - j) : n);
        }
        int ans = 0;
        rep(i, 1, m)
            ans += mn[i];
        cout << ans << endl;
    }
}

J Serval and Essay

链接:https://ac.nowcoder.com/acm/contest/33186/J
来源:牛客网

题目描述

Serval is a new student in Japari Kindergarten.

There is an English course in the kindergarten. The teacher sets some writing tasks for students to improve their writing skills. Therefore, Serval has to complete an essay, in English.

You might know that in an essay, the author has to convince readers of several arguments by showing them evidence.

Serval have collected nnn available arguments numbered from 111 to nnn that can be written in his essay. For the iii-th argument, Serval can conclude that iii-th argument is true when the arguments numbered ai,1,ai,2,…,ai,kia_{i,1}, a_{i,2}, \dots, a_{i,k_i}ai,1​,ai,2​,…,ai,ki​​ are all true. Specially, the iii-th argument cannot be proven true by making conclusion when ki=0k_i = 0ki​=0. It is guaranteed that ai,j≠ia_{i,j}\neq iai,j​​=i for all iii (1≤i≤n1\leq i\leq n1≤i≤n), and ai,j≠ai,ka_{i,j}\neq a_{i,k}ai,j​​=ai,k​ when j≠kj\neq kj​=k.

At the beginning of his essay, Serval will set exactly one argument from all the arguments as the argument basis, which is regarded as true. Starting with the argument basis, Serval will claim that some other arguments are true by making conclusions to complete his essay. It can be shown that for the iii-th argument with ki=0k_i = 0ki​=0, it can be true if and only if it is the argument basis.

Serval wants to maximize the number of true arguments in the essay, so he needs to set the argument basis optimally. However, as a kindergarten student, he cannot even find out the number of true arguments he can obtain.

Could you help him find out the answer?

输入描述:

Each test contains multiple test cases.

The first line contains an integer TTT (1≤T≤1051\leq T\leq 10^51≤T≤105) — the number of test cases.

For each test case:

The first line contains a single integer nnn (1≤n≤2×1051\leq n\leq 2\times 10^51≤n≤2×105) — the number of the available arguments.

For the iii-th line in the following nnn lines, there is an integer kik_iki​ (0≤ki<n0\le k_{i} < n0≤ki​<n) followed by kik_iki​ integers ai,1,ai,2,…,ai,kia_{i,1},a_{i,2},\dots,a_{i,k_i}ai,1​,ai,2​,…,ai,ki​​ (1≤ai,j≤n,ai,j≠i1\le a_{i,j}\le n,a_{i,j}\neq i1≤ai,j​≤n,ai,j​​=i) — the arguments required to make the conclusion for the iii-th argument. It is guaranteed that ai,j≠ia_{i,j}\neq iai,j​​=i for all iii (1≤i≤n1\leq i\leq n1≤i≤n), and ai,j≠ai,ka_{i,j}\neq a_{i,k}ai,j​​=ai,k​ when j≠kj\neq kj​=k.

It is guaranteed that the sum of nnn in all the test cases does not exceed 2×1052\times 10^52×105 and the sum of kik_iki​ in all the test cases does not exceed 5×1055\times 10^55×105.

输入

3
4
0
1 1
2 1 2
2 2 3
5
1 3
1 1
1 2
1 5
4 1 2 3 4
7
0
2 1 4
1 2
1 3
2 3 4
1 1
2 5 6

输出

Case #1: 4
Case #2: 3
Case #3: 4

一个命题需要若干个和它相关的命题证明,问通过一个基本命题能证明的最大命题数量

如果一个命题只需要一个命题证明时,那我们直接证明它的父命题即可,然后我们考虑把这两个命题进行合并,用set储存边,然后把被吞并的命题能证明的命题的入度减一,那么如果减一的命题最后入度也只剩下一了,那就是这个大集合对应指向的,继续进行合并即可

tags:启发式搜索 (并查集)

AC代码

/****************
 *@description:for the Escape Project
 *@author: Nebula_xuan
 * @Date: 2022-07-23 01:10:38
 *************************************************************************/

#include <bits/stdc++.h>

using namespace std;

const int N = 4e5 + 10;
int fa[N], siz[N];
set<int> to[N], fo[N];
typedef pair<int, int> PII;
int find(int x)
{
    if (fa[x] == x)
        return x;
    return fa[x] = find(fa[x]);
}
void merge(int x, int y)
{
    x = find(x), y = find(y);
    if (x == y)
        return;
    if (to[x].size() < to[y].size())
        swap(x, y);
    fa[y] = x;
    siz[x] += siz[y];
    vector<PII> temp;
    for (auto it : to[y])
    {
        to[x].insert(it);
        fo[it].erase(y);
        fo[it].insert(x);
        if (fo[it].size() == 1)
            temp.push_back({it, x});
    }
    for (auto it : temp)
        merge(it.first, it.second);
}
int main()
{
    int t;
    cin >> t;
    for (int idx = 1; idx <= t; idx++)
    {
        int n;
        cin >> n;
        for (int i = 1; i <= n; i++)
            fa[i] = i, siz[i] = 1;
        for (int i = 1; i <= n; ++i)
            to[i].clear(), fo[i].clear();
        for (int i = 1; i <= n; i++)
        {
            int k;
            cin >> k;
            for (int j = 1; j <= k; j++)
            {
                int y;
                cin >> y;
                to[y].insert(i);
                fo[i].insert(y);
            }
        }
        for (int i = 1; i <= n; i++)
        {
            if (fo[i].size() == 1)
                merge(*fo[i].begin(), i);
        }
        int ans = 0;
        for (int i = 1; i <= n; i++)
            ans = max(ans, siz[i]);
        printf("Case #%d: %d\n", idx, ans);
    }
}

I Chiitoitsu

题目描述

You may know that in Japanese Mahjong, winning a hand requires at least one yaku, where hand denotes the tiles a player holds. There are a large number of yaku types, and among them, Serval loves chiitoitsu most. Chiitoitsu is the hand that consists of seven distinct pairs. In other words, chiitoitsu consists of seven distinct types of tiles and two tiles of each type. In this problem, there is no need for you to learn what yaku exactly is. You only need to focus on chiitoitsu.

Serval loves chiitoitsu so much that he wants to practice winning hands with chiitoitsu. Note that the rules that Serval practices seeking chiitoitsu are different from those of Japanese Mahjong. At first, all the tiles are shuffled and placed face-down on the board as the stockpile. Then the only player, Serval, is dealt 13 tiles, which means that he will get 13 tiles from the stockpile. These 13 tiles are called the start hand. In each turn, Serval can draw and discard in the following order:

  • Draw a tile from the stockpile.

    Serval gets a random tile from the stockpile. After that, he will hold 14 tiles.

  • Tsumo if the hand reaches chiitoitsu.

    Serval declares a win immediately if his hand reaches chiitoitsu, and the game is over at the same time.

  • Discard a tile from the hand.

    Serval chooses a tile and removes it from his hand. After that, he will hold 13 tiles. The discarded tile will be placed face-up on the board, which means it will not return to the stockpile.

Now Serval gets his start hand, and he wonders the expected number of turns to reach chiitoitsu if he carries out the optimal strategy. Surprisingly, Serval finds that there are no more than two tiles of the same type in his start hand. Serval simply concatenates the notation of each tile in the start hand, forming a string of 26 characters to describe the start hand. However, Serval cannot find out the answer, so he tells you his start hand and asks you to help him. You only need to tell him the answer modulo 109+710^9+7109+7.

It can be shown that the answer can be represented as a fraction p/qp/qp/q, where ppp and qqq are both positive integers and coprime. If there exists a non-negative integer rrr less than 109+710^9+7109+7 satisfying q⋅r mod (109+7)=pq \cdot r \bmod (10^9+7) = pq⋅rmod(109+7)=p, we call the integer rrr the result of p/qp/qp/q modulo 109+710^9+7109+7.

给你13张牌,每次摸一张打一张,求最优策略出牌有七个对子时的期望
本题是期望DP,很容易想到最优策略就是如果新摸到的牌能和手中的单牌凑出对子就留着,并随便打出一张手里单牌,否则就把摸到的牌打出
不妨设 f [ i ] [ j ] f[i][j] f[i][j]表示已经摸了i张牌,手里还有j张单牌的情况
那么当前牌堆中还有136-i-13张牌,设为a
摸到手中单牌的期望是 3 j a ( 1 + f i − 1 , j − 2 ) \frac{3j}{a}(1+f_{i-1,j-2}) a3j(1+fi1,j2),那么摸到非手中单排的期望为 a − 3 j a ( 1 + f i − 1 , j ) \frac{a-3j}{a}(1+f_{i-1,j}) aa3j(1+fi1,j)

tags:期望DP 记忆化搜索

AC代码

/****************

 *@description:for the Escape Project

 *@author: Nebula_xuan

 * @Date: 2022-07-22 11:03:10

 *************************************************************************/

  

#include <iostream>

#include <algorithm>

#include <cstring>

#include <cstdio>

using namespace std;

#define rep(i, h, t) for (int i = h; i <= t; i++)

#define dep(i, t, h) for (int i = t; i >= h; i--)

#define endl char(10)

#define int long long

typedef pair<int, int> PII;

typedef long long ll;

  

const int p = 1e9 + 7;

int f[200][14];

int b[20];

int inv(int a, int b = p - 2)

{

    int res = 1;

    while (b)

    {

        if (b & 1)

            res = res * a % p;

        a = a * a % p;

        b >>= 1;

    }

    return res;

}

int dfs(int a, int c)

{

    if (c < 0)

        return 0;

    if (f[a][c] != -1)

        return f[a][c];

    int res = 0;

    if (123 - a - 3 * c)

        res += 1ll * (123 - a - c * 3) * inv(123 - a) % p * dfs(a + 1, c) % p;

    res += 1ll * (3 * c) * inv(123 - a) % p * dfs(a + 1, c - 2) % p;

    return f[a][c] = (res + 1) % p;

}

signed main()

{

    ios::sync_with_stdio(false);

    memset(f, -1, sizeof f);

    int t;

    cin >> t;

    rep(k, 1, t)

    {

        string a;

        cin >> a;

        a = " " + a;

        rep(i, 1, 13)

        {

            b[i] = (a[i * 2 - 1] - '0') * 100 + (a[i * 2] - 'a');

        }

        sort(b + 1, b + 14);

        int v = 0;

        rep(i, 1, 12)

        {

            if (b[i] == b[i + 1])

                v++;

        }

        printf("Case #%d: %lld\n", k, (dfs(0, 13 - 2 * v)) % p);

    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nebula_xuan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值