首页 > 其他分享 >D. Monocarp and the Set

D. Monocarp and the Set

时间:2023-10-17 16:56:57浏览次数:42  
标签:Set Monocarp int text ret set mod

D. Monocarp and the Set

Monocarp has $n$ numbers $1, 2, \dots, n$ and a set (initially empty). He adds his numbers to this set $n$ times in some order. During each step, he adds a new number (which has not been present in the set before). In other words, the sequence of added numbers is a permutation of length $n$.

Every time Monocarp adds an element into the set except for the first time, he writes out a character:

  • if the element Monocarp is trying to insert becomes the maximum element in the set, Monocarp writes out the character >;
  • if the element Monocarp is trying to insert becomes the minimum element in the set, Monocarp writes out the character <;
  • if none of the above, Monocarp writes out the character ?.

You are given a string $s$ of $n-1$ characters, which represents the characters written out by Monocarp (in the order he wrote them out). You have to process $m$ queries to the string. Each query has the following format:

  • $i$ $c$ — replace $s_i$ with the character $c$.

Both before processing the queries and after each query, you have to calculate the number of different ways to order the integers $1, 2, 3, \dots, n$ such that, if Monocarp inserts the integers into the set in that order, he gets the string $s$. Since the answers might be large, print them modulo $998244353$.

Input

The first line contains two integers $n$ and $m$ ($2 \le n \le 3 \cdot 10^5$; $1 \le m \le 3 \cdot 10^5$).

The second line contains the string $s$, consisting of exactly $n-1$ characters <, > and/or ?.

Then $m$ lines follow. Each of them represents a query. Each line contains an integer $i$ and a character $c$ ($1 \le i \le n-1$; $c$ is either <, >, or ?).

Output

Both before processing the queries and after each query, print one integer — the number of ways to order the integers $1, 2, 3, \dots, n$ such that, if Monocarp inserts the integers into the set in that order, he gets the string $s$. Since the answers might be large, print them modulo $998244353$.

Examples

input

6 4
<?>?>
1 ?
4 <
5 <
1 >

output

3
0
0
0
1

input

2 2
>
1 ?
1 <

output

1
0
1

Note

In the first example, there are three possible orderings before all queries:

  • $3, 1, 2, 5, 4, 6$;
  • $4, 1, 2, 5, 3, 6$;
  • $4, 1, 3, 5, 2, 6$.

After the last query, there is only one possible ordering:

  • $3, 5, 4, 6, 2, 1$.

 

解题思路

  这题关键是能想到反过来去考虑问题,即依次删除集合中的元素,这与原问题是等价的。具体来讲就是,假设一开始集合含有元素 $1 \sim n$,那么对于第 $i$ 次的删除操作,分以下三种情况:

  • 如果 $s_{n-i} = \text{<}$,那么删除此时集合中最小的元素,只有一种选择。
  • 如果 $s_{n-i} = \text{>}$,那么删除此时集合中最大的元素,只有一种选择。
  • 如果 $s_{n-i} = \text{?}$,那么删除此时集合中既不是最大也不是最小的元素,此时集合的大小为 $n-i+1$,因此有 $n-i-1$ 种选择。

  可以发现每一次的删除操作都是独立的,因为我们并不关心此时集合中具体有哪些元素(满足相对大小即可),只关心集合的大小以及是否删除最值。因此如果 $s_i = \text{?}$,那么就有 $i-1$ 中选择(集合大小为 $i+1$),否则就只有一种选择。所以原始的 $s$ 的合法方案的数量就是 $p = \prod\limits_{\begin{array}{c} i=1 \\ s_i = \text{?} \end{array}}^{n-1}{(i-1)}$。

 由于每一次的删除操作都是独立的,因此对于每个询问我们只需在对应的位置修改然后维护 $p$ 即可。可以用线段树来维护区间区间乘积,单点修改。或者用乘法逆元,不过需要注意的是如果 $s_1$ 在修改前是 $\text{?}$,那么我们会出现除以 $0$ 的情况。为此我们可以单独处理 $s_1$,维护一个 $t$,以及维护 $s_2 \sim s_{n-1}$ 对应的乘积 $p$。如果修改后 $s_1 = \text{?}$,则 $t = 0$,否则 $t = 1$,那么每个询问的答案就是 $t \cdot p$。

  线段树做法,AC 代码如下,时间复杂度为 $O(m \log{n})$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 3e5 + 10, mod = 998244353;

char s[N];
struct Node {
    int l, r, p;
}tr[N * 4];

void build(int u, int l, int r) {
    tr[u] = {l, r};
    if (l == r) {
        if (s[l] == '?') tr[u].p = l - 1;
        else tr[u].p = 1;
    }
    else {
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build(u << 1 | 1, mid + 1, r);
        tr[u].p = 1ll * tr[u << 1].p * tr[u << 1 | 1].p % mod;
    }
}

void modify(int u, int x, int c) {
    if (tr[u].l == tr[u].r) {
        tr[u].p = c;
    }
    else {
        if (x <= tr[u].l + tr[u].r >> 1) modify(u << 1, x, c);
        else modify(u << 1 | 1, x, c);
        tr[u].p = 1ll * tr[u << 1].p * tr[u << 1 | 1].p % mod;
    }
}

int main() {
    int n, m;
    scanf("%d %d %s", &n, &m, s + 1);
    build(1, 1, n - 1);
    for (int i = 0; i < m + 1; i++) {
        printf("%d\n", tr[1].p);
        int x;
        char c[5];
        scanf("%d %s", &x, c);
        if (c[0] == '?') modify(1, x, x - 1);
        else modify(1, x, 1);
    }
    
    return 0;
}

  乘法逆元做法,AC 代码如下,时间复杂度为 $O(m \log{\operatorname{mod}})$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 3e5 + 10, mod = 998244353;

char s[N];

int qmi(int a, int k) {
    int ret = 1;
    while (k) {
        if (k & 1) ret = 1ll * ret * a % mod;
        a = 1ll * a * a % mod;
        k >>= 1;
    }
    return ret;
}

int main() {
    int n, m;
    scanf("%d %d %s", &n, &m, s + 1);
    int ret = 1;
    for (int i = 2; i < n; i++) {
        if (s[i] == '?') ret = ret * (i - 1ll) % mod;
    }
    for (int i = 0, t = s[1] != '?'; i < m + 1; i++) {
        printf("%d\n", ret * t);
        int x;
        char c[5];
        scanf("%d %s", &x, c);
        if (x == 1) {
            t = c[0] != '?';
        }
        else {
            if (s[x] == '?') ret = 1ll * ret * qmi(x - 1, mod - 2) % mod;
            if (c[0] == '?') ret = ret * (x - 1ll) % mod;
        }
        s[x] = c[0];
    }
    
    return 0;
}

 

参考资料

  Educational Codeforces Round 156 Editorial:https://codeforces.com/blog/entry/121255

标签:Set,Monocarp,int,text,ret,set,mod
From: https://www.cnblogs.com/onlyblues/p/17770113.html

相关文章

  • RTMP dimensions not set问题解决方案
    问题RTMP开始推流,打印错误提示:dimensionsnotset源码位置libavformat\mux.ccaseAVMEDIA_TYPE_VIDEO:if((par->width<=0||par->height<=0)&&!(of->flags&AVFMT_NODIMENSIONS)){av_log(s,A......
  • @SuppressLint("NotifyDataSetChanged")
    @SuppressLint("NotifyDataSetChanged")注解的功能是用于在Android开发中抑制与notifyDataSetChanged方法相关的Lint警告或错误。在Android开发中,当你使用适配器(例如ArrayAdapter、BaseAdapter等)来填充ListView或RecyclerView等视图时,通常会调用notifyDataSetChanged方法,以通知......
  • elasticsearch通过Java class类的@Setting和@Mapping来定义索引index
    今天就来和大家讲讲如何将es索引中的mapping和setting在索引index和class联系起来,其实在这个问题也困扰我好久了,一直没有解决,在elasticsearch7.x版本的时候貌似好像可以用request在程序中来建立索引,像Stringindex=“{“mapping”:...}”之类的操作,干起来比较复杂,在elasticsearch......
  • 03 K8S API资源对象介绍02(Deployment Service DaemonSet StatefulSet)
    一、API资源对象DeploymentDeploymentYANL示例vimnginx-deploy.yamlapiVersion:apps/v1kind:Deploymentmetadata:labels:app:myngname:ng-deployspec:replicas:2##副本数selector:matchLabels:app:myngtemplate:metadata:......
  • vue3中setup
    和vue2不同的是vue3中的script中带有setup标签里面的setup相当于vue2中的data和methds空间可以放置函数,也可以执行函数在写时需要有return返回值<scriptsetup></script>setup执行发生在页面之前所以不能使用this函数,一般通过ref绑定组件上的值进行修改 使用函数例子......
  • Count of Sub-Multisets With Bounded Sum
    CountofSub-MultisetsWithBoundedSumYouaregivena 0-indexed array nums ofnon-negativeintegers,andtwointegers l and r.Return the countofsub-multisets within nums wherethesumofelementsineachsubsetfallswithintheinclusiv......
  • cpu亲和性相关函数和宏 基础讲解[cpu_set_t]
    cpu亲和性相关函数和宏讲解:写在前面:我在查找关于linuxcpu宏函数没看到有对宏函数基础的、详细的讲解,笔者便通过官方文档入手,对次进行的翻译和理解希望能帮到对这方面宏有疑惑的读者explain:/elem/表示为elem变量,这样子便于区分P.S:#include<sched.h>动态范围cpu设置......
  • 完美解决XDG_RUNTIME_DIR not set, defaulting to ‘/tmp/runtime-root‘
    完美解决XDG_RUNTIME_DIRnotset,defaultingto‘/tmp/runtime-root‘源代码杀手已于2023-01-1112:53:46修改阅读量4.1w收藏49点赞数13分类专栏:报错记录文章标签:linux版权报错记录专栏收录该内容19篇文章0订阅订阅专栏警告:对Linux不熟悉的人慎重使用,为了保险起......
  • mysql报错:You must reset your password using ALTER USER statement before executin
    新安装mysql后,登录后,执行任何命令都会报错:YoumustresetyourpasswordusingALTERUSERstatementbeforeexecutingthisstatement.【解决办法】MySQL版本5.7.6版本以前用户可以使用如下命令:mysql>SETPASSWORD=PASSWORD('Admin2022!');MySQL版本5.7.6版本开始的用户可以使......
  • <script setup> 语法糖作用
    <scriptsetup>constmsg='信息详情'constclickMsg=()=>{console.log(2223323)}</script><template><div>{{msg}}</div><br><button@click="clickMsg">按钮</button></tem......