首页 > 其他分享 >AtCoder Beginner Contest 295

AtCoder Beginner Contest 295

时间:2023-04-16 20:02:32浏览次数:40  
标签:std AtCoder const Beginner int cin 次数 295 find

Three Days Ago

我们定义一个只由数字构成的字符串中的字符能够被重排成相同的两份,我们称这个字符串是个好字符串,比如12341234

现在给定一个字符串\(S\),找出所有的\([l,r]\),使得在这段区间中的子段是个好字符串

题解:思维 + 组合计数

首先我们根据题意得到:一个好字符串中所有相同数字出现的次数一定是偶数

我们考虑维护一个前缀\(0-9\)每个数字出现次数的奇偶性的状态

  20230322
0:00000000
1:00100000
2:10100000
3:10000000
4:10010000
5:00010000
6:00000000
7:00100000
8:00000000

我们发现如果前缀\(i\)时的状态等于前缀\(j\)时的状态,说明在\([i+1,j]\)这段区间中每个数字出现的次数都为偶数次,因为如果前缀\(j\)的状态中数字\(x\)出现的次数为奇数次,前缀\(i\)的状态中数字\(x\)出现的次数也是奇数次,说明\([i+1,j]\)之间\(x\)出现的次数一定为偶数;如果\(x\)出现的次数为偶数次不再赘述

所以我们不妨使用哈希表记录每个状态出现的次数,然后如果某个状态出现超过两次,说明一定有合法的区间,我们利用组合计数求出贡献即可

#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 5e5 + 10, M = 4e5 + 10;

map<string, int> mp;
int cnt[10];

void solve()
{
    string s;
    cin >> s;
    int n = s.length();
    string t = "0000000000";
    mp[t]++;
    s = " " + s;
    for (int i = 1; i <= n; ++i)
    {
        cnt[s[i] - '0']++;
        if (cnt[s[i] - '0'] % 2 == 0)
            t[s[i] - '0'] = '0';
        else
            t[s[i] - '0'] = '1';
        mp[t]++;
    }
    int ans = 0;
    for (auto [x, y] : mp)
    {
        ans += y * (y - 1) / 2;
    }
    cout << ans << endl;
}
signed main(void)
{
    Zeoy;
    int T = 1;
    // cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

Minimum Reachable City

给定一颗点数为 \(N\) 的树,初始 \(p_i(1\leq p_i \leq i,1 \leq i < N)\) 连向 \(i+1\)。

\(Q\) 次操作,有两种:

  • 1 u v:\(u\) 向 \(v\) 连一条有向边,保证最开始时 \(v\) 能到达 \(u\),\(u \ne v\)。
  • 2 x:询问 \(x\) 能到达的点中编号最小的点。

题解:并查集 \(O(n\alpha(n))\)

我们发现在这颗树上,祖先节点的编号一定小于当前节点的编号;

因为我们又知道操作\(1\)的时候保证\(v\)能到达\(u\),也就是说\(v\)的编号一定比\(u\)小,也就是说\(u\)向\(v\)连的一条有向边一定是返祖边,所以如果\(u\)向\(v\)连的一条有向边,那么\(v\)到\(u\)这条链之间的所有点都能够到达\(v\),所以对于操作\(2\)来说我们不妨利用并查集维护根节点,在合并节点时我们考虑暴力往上合并,我们发现这颗树上的点最多只会被遍历一次,加上合并时的复杂度,最终复杂度为\(O(n\alpha(n))\)

#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10, M = 4e5 + 10;

int n, q;
int fa[N];
int par[N];

int find(int x)
{
    return x == fa[x] ? x : fa[x] = find(fa[x]);
}

void merge(int u, int v)
{
    u = find(u);
    v = find(v);
    if (u != v)
        fa[u] = v;
}

void solve()
{
    cin >> n;
    for (int i = 1; i <= n; ++i)
        fa[i] = i;
    for (int i = 1; i < n; ++i)
    {
        int x;
        cin >> x;
        par[i + 1] = x;
    }
    cin >> q;
    while (q--)
    {
        int op, u, v;
        cin >> op;
        if (op == 1)
        {
            cin >> u >> v;
            for (int p = u; p > v; p = par[p])
            {
                p = find(p);
                merge(p, v);
            }
        }
        else
        {
            cin >> u;
            cout << find(u) << endl;
        }
    }
}
signed main(void)
{
    Zeoy;
    int T = 1;
    // cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

标签:std,AtCoder,const,Beginner,int,cin,次数,295,find
From: https://www.cnblogs.com/Zeoy-kkk/p/17322921.html

相关文章

  • Atcoder题解:Agc002_f
    我们可以把这个理解成一种类似卡塔兰数的形式,我们发现,被安排的\(0\)球总数\(i\)和已经出现的颜色种数\(j\)在任意时刻都必须满足\(i\gej\)。然后就可以\(dp\)了,我们每次钦定下一个转移的球是某种颜色。如果下一个转移的球不是\(0\),那么我们就一次性把后面所有这种颜色......
  • Atcoder题解:Agc004_e
    \[吓死我了,还以为写了半天的被自己删掉了\]\[但是\text{Ctrl+S}会保存草稿啊\]\[以后一定要保留这个好习惯\]第一步转化题意,我们把“所有机器人移动”转化成“出口带着边框移动”,而在出口运动过程中超出边框的机器人,就“死”了。然后我们发现,出口运动过程中,假设出口目前走到......
  • Atcoder题解:Agc013_e
    我们考虑转化题意,一个合法的将\(1\simN\)划分成长度依次为\(a_1,a_2,\cdotsa_k\)的小区间,对答案的贡献为\(a_1^2a_2^2\cdotsa_k^2\)。化贡献为方案数,我们在每个长度为\(a_i\)的小区间内放置两个独立的标记,每个合法的划分方案对放置标记方案种数的贡献恰好是其对最终答......
  • AtCoder 板刷 / vp 记录
    ARC104AtCoder传送门A题解一道小学数学题,$X=\frac{A+B}{2},Y=\frac{A-B}{2}$。B题解一道暴力题。发现子串合法的充要条件是$cnt_{\text{A}}=cnt_{\text{T}}\landcnt_{\text{G}}=cnt_{\text{C}}$,暴力统计即可。C题解简单区间dp。发现$[1,2n]$可以拆......
  • AtCoder Regular Contest 104 F Visibility Sequence
    洛谷传送门AtCoder传送门考虑连边\((i,p_i)\)(若\(p_i=-1\)则不连边),可以发现形成了一篇内向树森林且这个森林存在一个dfs序为\(1,2,...,n\)。这棵森林有如下性质:\(\forallv\inson_u,h_u>h_v\)\(\forallv,w\inson_u\landv<w,h_v\leh_w\)考虑一个\(p......
  • AtCoder Beginner Contest 223(D,E,F)
    AtCoderBeginnerContest223(D,E,F)D(拓扑排序)D大意就是有\(n\)个点,\(m\)个关系,其中关系是指\(u\)和\(v\),在排序里面使得\(u\)的位置再\(v\)的位置的前面要求找到一个排序满足上述条件的序列中字典序最小的那一个这个使用拓扑排序,并加上优先队列即可只要找到\(n\)个数,即为......
  • AtCoder Beginner Contest 293 补题记录 (E-G)
    E题意:给定A,X,M,计算(A0+A1+A2+...+AX-1)modM(1<=A,M<=109,1<=X<=1012)。 根据等比数列求和公式,(A0+A1+A2+...+AX-1)modM=((AX-1)/(A-1))modM。然而,此题如果用求和公式来求解显然是行不通的,下面会给出原因。 如果我们要用求......
  • AtCoder Regular Contest 104 D Multiset Mean
    洛谷传送门AtCoder传送门很平凡的一道计数啊。考虑将所有数都减去\(x\),那么就要求选的数和为\(0\)。正负分开考虑,\(0\)可以任意选。需要多重背包求\(f_{i,j}\)表示选\(1\simi\)的数和为\(j\)的方案数。前缀和优化是平凡的。code//Problem:D-MultisetMean......
  • UVA 12295 Optimal Symmetric Paths 最短路求方案数
    题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=23587题意:给一个n*n的矩阵,每个方格中有一个数字,从左上角走到右下角,且路径必须关于副对角线对称,求使路线上数字和最小的方案数思路:既然要关于副对角线对称,那么可以把关于副对角线对称的方格的值加到一起去,这样就......
  • AtCoder Beginner Contest 297
    A-DoubleClick#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongint32_tmain(){intn,d;cin>>n>>d;vector<int>a(n);for(auto&i:a)cin>>i;for(inti=1;i<......