首页 > 其他分享 >AtCoder ABC 367

AtCoder ABC 367

时间:2024-08-20 14:05:24浏览次数:12  
标签:std AtCoder code int MAX ABC 数组 using 367

前言

本题解部分思路来自于网络,仅供参考。

A - Shout Everyday

题目大意

给定 Takahashi 每天的睡觉时间和起床时间,求 Takahashi 在 $A$ 时是睡着的还是清醒的。

解题思路

根据题意模拟即可。

code

#include <bits/stdc++.h>
using namespace std;
int main() {
    int a,b,c;
    cin >> a >> b >> c;
    if(b >= c) { //如果睡到了第二天
        c += 24;
    }
    if((b <= a && a <= c) | (b <= a + 24 && a + 24 <= c)) {
        printf("No\n");
    } else {
        printf("Yes\n");
    }
    return 0;
}

B - Cut .0

题目大意

给定一个有三位小数的浮点数,输出这个浮点数去除多余的 $0$ 和小数点后的数。

解题思路

直接输入这个数再输出即可。

code

#include <bits/stdc++.h>
using namespace std;
int main() {
    double x;
    scanf("%lf", &x);
    printf("%g\n", x);
    return 0;
}

C - Enumerate Sequences

题目大意

给定一个序列 $R$ ,按字典序所有长度为 $K$ 的,满足以下两个条件的数列:

  1. 数列的第 $i$ 个元素在 $[1,R_i]$ 之间。
  2. 数列和是 $K$ 的倍数。

解题思路

直接用dfs枚举即可。

code

#include <bits/stdc++.h>
using namespace std;
int r[15];
int ans[15];
int n, k;
void print() {
    for (int i = 1; i <= n; i++) {
        printf("%d ", ans[i]);
    }
    puts("");
}
void dfs(int ind, int sum) {
    if (ind == n + 1) {
        if (sum % k == 0) {
            print();
        }
        return;
    }
    for (int i = 1; i <= r[ind]; i++) {
        ans[ind] = i;
        dfs(ind + 1, sum + i);
    }
}
int main() {
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; i++) {
        scanf("%d", r + i);
    }
    dfs(1, 0);
    return 0;
}

D - Pedometer

题目大意

给出湖边 $N$ 个休息区中从一个休息区顺时针走到下一个休息区需要走的部署,求满足休息区 $s$ 顺时针走到休息区 $t$ 需要走的步数为 $M$ 的倍数,$(s,t)$ 对的个数。

解题思路

因为湖边 $N$ 个休息区在一个环上,考虑把输入的数组复制一遍,即把 $[2,1,4,3]$ 变成 $[2,1,4,3,2,1,4,3]$ 。

为了快速求出两个休息区之间的距离,我们对复制过后的数组做前缀和,复制过后的数组前缀和过后得到数组 $s$ 。

为了快速得出哪些区间的区间和是 $M$ 的倍数,我们进行分析。如果区间 $[i,j]$ 的区间和是 $M$ 的倍数,即 $s_j - s_{i - 1}\bmod M=0$ ,则:

$$ \because s_j - s_{i - 1} \bmod M = 0 \\ \therefore s_j - s_{i - 1} \equiv 0 \pmod{M} \\ \therefore s_j \equiv s_{i - 1} \pmod{M} $$

所以,当 $s_j \equiv s_{i - 1} \pmod{M}$ 时,区间 $[i,j]$ 的区间和为 $M$ 的倍数。为了得出与 $s_i$ 同模的数,我们维护一个 $map$ ,$map[i]$ 表示有多少个 $s_j$ 满足 $s_j \bmod M = i$ 。每处理一个 $s_i$ ,答案就增加 $map[s_i \bmod M]$ ,并把 $s_i$ 加入 $map$ ,弹出 $s_{i - N + 1}$ 。

code

#include <bits/stdc++.h>
using namespace std;
int a[400005];
int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%d", a + i);
        a[i + n] = a[i];
    }
    for (int i = 1; i <= 2 * n; i++) {
        a[i] += a[i - 1];
        a[i] %= m;
    }
    unordered_map<int, int> cnt;
    long long res = 0;
    for (int i = 2; i <= n; i++) cnt[a[i]]++;
    for (int i = n + 1; i <= 2 * n; i++) {
        res += cnt[a[i]];
        cnt[a[i]]++;
        cnt[a[i - n + 1]]--;
    }
    printf("%lld\n", res);
    return 0;
}

[E - Permute K times](E - Permute K times (atcoder.jp))

题目大意

给定两个数组 $A$ 和 $X$ 和一个整数 $K$ ,求 $A$ 在进行了 $K$ 次操作

$$ A_i = A_{X_i} $$

以后变成了什么。

解题思路

这道题可以看作一道图论题。

$A$ 数组的每一位可以看作图的节点,$K$ 数组的每一位可以看作图的边。

而每一次操作都可以看作是点在图上的运动。

为了快速求出每一个点在运动了 $K$ 步后到了哪里,我们维护一个倍增数组 $x[i][j]$ 表示第 $i$ 个点走了 $2^j$ 步后到了哪里。之后用倍增数组求出每一个点在进行了 $K$ 次操作之后到了哪里,最后输出结果。

code

#include <bits/stdc++.h>
using namespace std;
int a[200005];
int x[200005][64];
int main() {
    int n;
    long long k;
    scanf("%d%lld", &n, &k);
    for (int i = 1, t; i <= n; i++) {
        scanf("%d", &t);
        x[i][0] = t;
    }
    for (int i = 1; i <= n; i++) {
        scanf("%d", a + i);
    }
    for (int i = 1; i <= 60; i++) {
        for (int j = 1; j <= n; j++) {
            x[j][i] = x[x[j][i - 1]][i - 1];
        }
    }
    for (int i = 1; i <= n; i++) {
        int p = i;
        for (int j = 60; j >= 0; j--) {
            if (k >> j & 1) p = x[p][j];
        }
        printf("%d ", a[p]);
    }
    puts("");
    return 0;
}

F - Rearrange Query

题目大意

给定两个数组 $A$ 和 $B$ ,对于每一次询问 $l_i,\ r_i,\ L_i,\ R_i$ ,回答可不可以通过排列 $A[l_i...r_i]$ 使得 $A[l_i...r_i] = B[L_i...R_i]$ 。

解题思路

这道题直接使用哈希+前缀和即可。

code

#include <bits/stdc++.h>
#define MOD 156876589475701
#define MAX_N 200005
using namespace std;
int a[MAX_N], h[MAX_N], b[MAX_N], ph1[MAX_N], ph2[MAX_N];
int main() {
    int n, q;
    scanf("%d%d", &n, &q);
    mt19937_64 mt(time(0));
    for (int i = 1; i <= n; i++) {
        h[i] = mt();
    }
    for (int i = 1; i <= n; i++) {
        scanf("%d", a + i);
        ph1[i] = (h[a[i]] + ph1[i - 1]) % MOD;
    }
    for (int i = 1; i <= n; i++) {
        scanf("%d", b + i);
        ph2[i] = (h[b[i]] + ph2[i - 1]) % MOD;
    }
    int l, r, L, R;
    while (q--) {
        scanf("%d%d%d%d", &l, &r, &L, &R);
        if (ph1[r] - ph1[l - 1] == ph2[R] - ph2[L - 1]) {
            puts("Yes");
        } else {
            puts("No");
        }
    }
    return 0;
}

标签:std,AtCoder,code,int,MAX,ABC,数组,using,367
From: https://www.cnblogs.com/sxloiblog/p/18369348

相关文章

  • ABC367
    Alink先判断一下时间是否跨天,如果跨天了,把后一个加上\(24\),使后一个大于前一个,再判断国王喊的时间或喊的时间加\(24\)是否在范围内。神奇的代码#include<bits/stdc++.h>usingnamespacestd;signedmain(){ inta,b,c; cin>>a>>b>>c; if(b>c)c+=24; ......
  • AT_abc027_b题解
    说明需要掌握贪心算法。这么简单为什么是黄题啊?题意给定一个长度为的非负整数序列,你可以进行若干次操作,每次操作都可以选择一个长度为的子串,花费的代价,将其中的每个数都变成该子串的平均值,现在你必须将每个数都变成相同的,你必须同时保证每个数为非负整数。分析先算......
  • [ABC367D] Pedometer-xzy巨佬简洁做法
    [ABC367D]Pedometer-xzy巨佬简洁做法https://www.luogu.com/article/n64n78cs对照巨佬的代码进一步理解//徐知鱼#include<bits/stdc++.h>usingnamespacestd;inlineintread(){ intx=0,f=1; charch=getchar(); while(!isdigit(ch)){ if(ch=='-')f=......
  • AtCoder Beginner Contest 367
    题目链接:AtCoderBeginnerContest367总结:发挥很一般,A一直wa。开场有点事,导致D也没debug出来。A.ShoutEverydaytag:模拟Solution:注意\(B>C\)与\(B<C\)的不同情况即可。voidsolve(){  inta,b,c;  cin>>a>>b>>c;  if(c>b){    if(......
  • 题解:AT_abc367_c [ABC367C] Enumerate Sequences
    大致题意让你按照字典序输出一些长\(n\)的序列,序列中的数字有范围,且序列和需要为\(k\)。分析直接深搜。搜索的时候对从第一个元素开始,每个元素从小到大枚举所有可能的值,这样就保证答案按照字典序升序排列。用一个vector存储序列,到达边界之后计算一遍和,判断是否满足条件,然......
  • ABC 367D Pedometer
    题意给定N个人成的环,第i个人到第i+1个人之前的距离为a[i](第N个人到第1个人的距离为a[n]),每个人只能顺时针走动。求问有多少点对(s,t)使得第s个人走到第t个人的距离是M的倍数。思路对于这种环状问题,我们最开始的思路就是开个双倍数组把环破坏成链转换成线性问题。接下来就是我们......
  • ABC 367 G 题解
    ABC367G神奇题目场上想到了引入多元生成函数之后就嗝屁了。定义两个多项式的运算\(A(z)*B(z)=\sum_{i}\sum_{j}z^{i\oplusj}a_ib_j\),也就是异或卷积。定义两个二元生成函数\(A(x,y)*B(x,y)=\sum_{i,p}\sum_{j,q}x^{i\oplusj}y^{p+q}a_{i,p}b_{j,q}\)我们仍然选用\(\prod......
  • [LeetCode] 1367. Linked List in Binary Tree 二叉树中的链表
    Givenabinarytree root anda linkedlistwith head asthefirstnode.ReturnTrueifalltheelementsinthelinkedliststartingfromthe head correspondtosome downwardpath connectedinthebinarytree otherwisereturnFalse.Inthiscontext......
  • 题解:AT_abc367_d [ABC367D] Pedometer
    首先肯定要单层循环枚举元素,然后想方法求出一个元素的所有答案。一开始我写了一个二分找\(m\)倍数的方法,发现\(m\)小的时候还不如暴力。于是联想到之前做过的一道题,可以借助于取模的前缀和数组。对于当前元素\(i\),如果一个元素之前的前缀和与\(i\)之前的前缀和对\(m\)......
  • Atcoder [ABC367F] Rearrange Query 题解
    简要题意给定两个长度为\(N\)的序列\(A\)和\(B\)。有\(Q\)个查询,每个查询给定\(l,r,L,R\),其中\(l\leqr,L\leqR\),要求判断\(A\)的第\(l\)项到第\(r\)项构成的集合与\(B\)的第\(L\)项到第\(R\)项构成的集合是否相等。题解显然两个相等的集合所有元素......