首页 > 其他分享 >[ABC268G] Random Student ID 题解

[ABC268G] Random Student ID 题解

时间:2023-02-15 19:11:28浏览次数:56  
标签:return 前缀 ABC268G 题解 ll Random ret int define

[ABC268G] Random Student ID Solution

目录

更好的阅读体验戳此进入

题面

给定 $ n $ 名学生的名字 $ S_i $,保证不重复。现在随机一个 $ a \rightarrow z $ 的排列作为字典序的偏序关系,求每个同学排名的期望,对 $ 998244353 $ 取模。

Solution

这一题可以说确实很高妙,确实没想到还可以这么处理。

第一眼以为是一些类似 期望DP 的东西,然后想了半天也没想到什么复杂度正确的做法,实际上这道题是从期望的意义去找性质。

首先我们考虑对于一个串 $ S $ 的期望排名,若存在串 $ S $ 的前缀串 $ T $,那么显然串 $ T $ 无论字典序的偏序关系如何都会在 $ S $ 之前,所以一定会贡献 $ 1 $。

而若存在 $ S $ 是 $ T $ 的前缀,那么显然 $ T $ 在 $ S $ 之后,则贡献一定为 $ 0 $。

对于其它的情况,显然会由 $ \texttt{LCP} $ 之后的第一个不同的字符决定,而对于这种显然在所有字典序关系中两者的偏序关系的概率是相同的,所以此时的贡献为 $ \dfrac{1}{2} $。那么对于字符串 $ S $,若其前缀串有 $ x $ 个,满足有 $ S $ 前缀的串有 $ y $ 个,那么答案即为:

\[x \times 1 + y \times 0 + (n - x - y - 1) \times \dfrac{1}{2} + 1 \]

然后对于求前缀,显然可以通过 Trie树 解决,同时也可以考虑一些更简单的方法:

开一个 unordered_set,往里面丢每个串的哈希值,然后对于每个串的每个前缀的哈希在里面查一下然后记录即可,最终复杂度 $ O(\sum \lvert S_i \rvert) $。

Code

#define _USE_MATH_DEFINES
#include <bits/stdc++.h>

#define PI M_PI
#define E M_E
#define npt nullptr
#define SON i->to
#define OPNEW void* operator new(size_t)
#define ROPNEW void* Edge::operator new(size_t){static Edge* P = ed; return P++;}

using namespace std;

mt19937 rnd(random_device{}());
int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
bool rnddd(int x){return rndd(1, 100) <= x;}

typedef unsigned int uint;
typedef unsigned long long unll;
typedef long long ll;
typedef long double ld;

#define MOD (998244353ll)
#define BASE (31ll)

template < typename T = int >
inline T read(void);

int N;
int cntx[510000], cnty[510000];
ll inv_2;
string S[510000];
unordered_map < unll, int > idx;

ll qpow(ll a, ll b){
    ll ret(1), mul(a);
    while(b){
        if(b & 1)ret = ret * mul % MOD;
        b >>= 1;
        mul = mul * mul % MOD;
    }return ret;
}

int main(){
    inv_2 = qpow(2, MOD - 2);
    N = read();
    for(int i = 1; i <= N; ++i){
        cin >> S[i];
        unll cur(0);
        for(auto c : S[i])(cur *= BASE) += c;
        idx.insert({cur, i});
    }
    for(int i = 1; i <= N; ++i){
        unll cur(0);
        for(auto c : S[i]){
            (cur *= BASE) += c;
            if(idx.find(cur) != idx.end())++cntx[i], ++cnty[idx[cur]];
        }cntx[i]--, cnty[i]--;
    }
    for(int i = 1; i <= N; ++i)
        printf("%lld\n", (cntx[i] + (N - cntx[i] - cnty[i] - 1) * inv_2 % MOD + 1) % MOD);
    fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
    return 0;
}

template < typename T >
inline T read(void){
    T ret(0);
    int flag(1);
    char c = getchar();
    while(c != '-' && !isdigit(c))c = getchar();
    if(c == '-')flag = -1, c = getchar();
    while(isdigit(c)){
        ret *= 10;
        ret += int(c - '0');
        c = getchar();
    }
    ret *= flag;
    return ret;
}

UPD

update-2023_01_18 初稿

标签:return,前缀,ABC268G,题解,ll,Random,ret,int,define
From: https://www.cnblogs.com/tsawke/p/17124349.html

相关文章

  • P9063 [yLOI2023] 分解只因数 题解
    P9063[yLOI2023]分解只因数题解题意分解给定的\(n\)的质因数,判断是否全为奇数。思想因为我不是黑子,所以我根本没考虑“只因”的发音对思路的极大提示。当我首次......
  • [ABC262D] I Hate Non-integer Number 题解
    [ABC262D]IHateNon-integerNumberSolution目录[ABC262D]IHateNon-integerNumberSolution更好的阅读体验戳此进入题面SolutionCodeUPD更好的阅读体验戳此进入......
  • 【题解】[Ynoi2013] 文化课
    题目分析:这个权值一看就可以使用线段树维护啊,因为很明显可以进行高效合并。对于区间合并其实就只是需要判断一下两个区间中间如果是乘号,那么造成的贡献要变成区间两边乘......
  • 【题解】CF280D k-Maximum Subsequence Sum
    题目分析:(可能是刚做完毒瘤Ynoi的原因,看这个4k的线段树感觉好简单)可以看一下这个查询的操作,最多\(k\)个不重线段的和的最大值,这个东西大概是网络流的经典题吧。具......
  • 【题解】Luogu P3939 数颜色
    题目分析:解法一:显然我们可以直接对每一种颜色建一棵线段树,然后剩下的操作就非常简单了。代码:点击查看代码#include<bits/stdc++.h>usingnamespacestd;constint......
  • hadoop之shuffle阶段相关面试题解析
    --思考1:map()方法写出的数据存储到哪里?                                  --内存中1、在内存中存有一个环形缓冲区,该缓冲......
  • [省选联考 2022] 填树 题解
    神奇dp。发现我看到dp大多数时候只会暴力。那我约等于退役了啊。题意:自己看。首先有一个显然的暴力。枚举一个最小值\(L\),然后区间就限定在了\([L,L+K]\)。那么普及......
  • NOIP2015 普及组 推销员题解
    原题链接给定一个数轴,数轴上有一些点,第\(i\)个点离起点的距离是\(S_i\),取走它要消耗\(A_i\)的代价,同时在数轴上每移动一格要\(1\)的代价,路线只能从数轴......
  • CSP2022 假期计划 题解
    给你一张\(n\)个点,\(m\)条边的无向图,每个点有点权,要求你在图中选出\(A\),\(B\),\(C\),\(D\)四个点,使得\(1\rightarrowA\rightarrowB\rightarrowC\righ......
  • DTOJ 2023.02.11 测试 题解
    DTOJ2023.02.11测试题解2023省选模拟Round#12\(100+8+50=158\)还行T2想到了,但是没写,我觉得写了也不一定写得出来,挺妙的T1题意http://59.61.75.5:18018/p/545......