首页 > 其他分享 >sol. ABC246Ex

sol. ABC246Ex

时间:2023-08-18 14:00:11浏览次数:45  
标签:begin ch end int sol ABC246Ex bmatrix dp

动态 DP 模板题

[ABC246Ex] 01? Queries

题目大意:给定一个长度为 \(N\) 且只包含 ?,1,0 的字符串 \(a\)。\(Q\) 次操作,每次操作会修改字符串中的一个字符,并求出此时整个字符串中本质不同的子序列个数。


众所周知,动态 DP 依然是 DP 的一种。

先考虑没有修改操作,那么本题变为一个普通的 DP,我们设 \(dp_{i,0/1}\) 分别表示到第 \(i\) 位,以 \(0/1\) 结尾的本质不同的子序列个数。

考虑转移,以 \(a_i\) 为 0 为例,那么在 \(1\) 到 \(i-1\) 之间的所有本质不同的子序列后都可以加第 \(i\) 位的这个 \(0\),这些串依旧本质不同且长度不小于 \(2\),再加上 0 自己本身这种串,又因为 \(a_i\) 为 \(0\),不可能形成更多的以 \(1\) 结尾的本质不同子序列,所以:

当 \(a_i\) 为 0 时,

  • \(dp_{i,0}=dp_{i-1,0}+(dp_{i-1,1}+1)\)

  • \(dp_{i,1}=dp_{i-1,1}\)

\(a_i\) 为 1? 的转移同理:

当 \(a_i\) 为 1 时,

  • \(dp_{i,0}=dp_{i-1,0}\)

  • \(dp_{i,1}=dp_{i-1,1}+(dp_{i-1,0}+1)\)

当 \(a_i\) 为 ? 时,

  • \(dp_{i,0}=dp_{i-1,0}+(dp_{i-1,1}+1)\)

  • \(dp_{i,1}=dp_{i-1,1}+(dp_{i-1,0}+1)\)

最终答案为 \(dp_{n,0}+dp_{n,1}\)。

如果对于每次修改,重新做一遍 DP,时间复杂度变为 \(\mathcal{O}(NQ)\),无法通过,注意到方程的转移是一个线性递推式,这启示我们用矩阵优化转移。我们把递推式写成矩阵的形式,可以用以下的式子描述:

\[S_{a_i}\begin{bmatrix} dp_{i-1,0} \\ dp_{i-1,1} \\ 1\end{bmatrix}=\begin{bmatrix} dp_{i,0} \\ dp_{i,1} \\ 1\end{bmatrix} \]

不难写出:

\[S_{0}=\begin{bmatrix} 1&1&1 \\ 0&1&0 \\ 0&0&1\end{bmatrix},S_{1}=\begin{bmatrix} 1&0&0 \\ 1&1&1 \\ 0&0&1\end{bmatrix},S_{?}=\begin{bmatrix} 1&1&1 \\ 1&1&1 \\ 0&0&1\end{bmatrix} \]

那么整个 DP 的转移可以用以下式子表示:

\[\prod_{i=1}^n S_{a_i} \times \begin{bmatrix}0\\0\\1\end{bmatrix} = \begin{bmatrix} dp_{n,0} \\ dp_{n,1} \\ 1\end{bmatrix} \]

本质上,一次修改字符的操作就是修改一个字符的转移矩阵。又由上面的式子可知要维护的信息是整个字符串的 \(S_{a_i}\) 的乘积。由于矩阵具有结合律,所以可以用线段树维护。时间复杂度为 \(O(k^3(N + Q \log N))\),本题中 \(k = 3\)。

#include<bits/stdc++.h>
#define int long long
#define L p<<1
#define R p<<1|1
#define mid ((l+r)>>1)
using namespace std;
const int INF=0x3f3f3f3f;
const int MOD=998244353;
const int N=100005;
int tot=0;
char a[N];
inline int read(){
    int w=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        w=(w<<1)+(w<<3)+(ch-48);
        ch=getchar();
    }
    return w*f;
}
struct Matrix{
    int x,y,val[5][5];
    inline void clear(int a,int b){
        x=a; y=b;
        for(int i=1;i<=x;i++)
            for(int j=1;j<=y;j++) val[i][j]=0;
    }
    inline void unit(int a,int b){
        assert(a==b);
        x=a; y=b;
        for(int i=1;i<=x;i++) 
            for(int j=1;j<=y;j++) val[i][j]=(i==j);
    } 
};
inline Matrix mult(Matrix a,Matrix b){
    Matrix ans;
    assert(a.y==b.x);
    ans.clear(a.x,b.y);
    for(int i=1;i<=a.x;i++){
        for(int k=1;k<=a.y;k++){
            if(!a.val[i][k]) continue;
            for(int j=1;j<=b.y;j++){
                ans.val[i][j]+=a.val[i][k]*b.val[k][j]%MOD;
                ans.val[i][j]=(ans.val[i][j]%MOD+MOD)%MOD;
            }
        }
    }
    return ans;
}
Matrix S1,S2,S3,res;
struct Segnode{
    Matrix val;
}tr[N<<2];
inline void Pushup(int p){
    tr[p].val=mult(tr[L].val,tr[R].val);
}
inline void Build(int p,int l,int r){
    if(l==r){
        if(a[l]=='0') tr[p].val=S1;
        else if(a[l]=='1') tr[p].val=S2;
        else tr[p].val=S3;
        return ;
    }
    Build(L,l,mid);
    Build(R,mid+1,r);
    Pushup(p);
}
inline void Modify(int p,int l,int r,int x,Matrix d){
    if(l==r){
        tr[p].val=d;
        return ;
    }
    if(x<=mid) Modify(L,l,mid,x,d);
    else Modify(R,mid+1,r,x,d);
    Pushup(p);
}
inline void Prework(){
    S1.unit(3,3);
    S1.val[1][2]=S1.val[1][3]=1;
    S2.unit(3,3);
    S2.val[2][1]=S2.val[2][3]=1;
    S3.unit(3,3);
    S3.val[1][2]=S3.val[1][3]=S3.val[2][1]=S3.val[2][3]=1;
}
signed main(){
    int n,Q;
    n=read();Q=read();
    scanf("%s",a+1);
    Prework();
    Build(1,1,n);
    while(Q--){
        int x=read();
        char c[2];
        scanf("%s",c+1);
        if(c[1]=='0') Modify(1,1,n,x,S1);
        else if(c[1]=='1') Modify(1,1,n,x,S2);
        else Modify(1,1,n,x,S3);
        res.clear(3,1);
        res.val[3][1]=1;
        res=mult(tr[1].val,res);
        printf("%lld\n",(res.val[1][1]+res.val[2][1])%MOD);
    }
    return 0;
}

标签:begin,ch,end,int,sol,ABC246Ex,bmatrix,dp
From: https://www.cnblogs.com/WTR2007/p/17583294.html

相关文章

  • SOLIDWORKS如何快速生成汇总BOM,SolidKits软件助您一臂之力
    物料清单是一个制造企业的核心文件数据。各个部门的活动都要用到物料清单,生产部门要根据物料清单来生产产品,库房要根据物料清单进行发料,财会部门要根据物料清单来计算成本,维修服务部门要通过物料清单了解需要什么备件等。但是各个部门需要用到的物料清单又不尽相同,因此再出物料清......
  • ARC 157 F Sol
    嫌弃讲题人的我,准备好好写一篇题解。linktoproblem观察数据范围:\(1\leN\le50\)。如果是\(20\),想到\(2^{20}\);如果是\(40\),想到\(2^{40\div2}\);若果是\(50\)呢?\(2^{25}\)有点大,于是想到\(2^{50\div3}\)。但是如何去凑?Hint\(N\)\(S\)\(T\)\(res\)\(6......
  • IPQ5018|Unlocking Affordable WiFi 6: The Ultimate Solution
    IPQ5018|UnlockingAffordableWiFi6:TheUltimateSolutionIntheeraoflightning-fastconnectivitydemands,findingtheperfectsynergybetweenperformance,efficiency,andcost-effectivenessisparamount.IntroducingtheDR5018-aWiFi6solutionthat......
  • Linux安装Solr-8.9.0
    Solr的工作原理可以简单地概括为以下几个步骤:1.索引创建:首先,Solr需要创建一个索引,用于存储要搜索的数据。索引是基于ApacheLucene构建的,它将文档拆分为字段,并对字段进行分析和标记化,以便进行更有效的搜索和匹配。2.数据导入:Solr可以从多种数据源导入数据,包括数据库、文件、Web......
  • [POI2014] PAN-Solar Panels
    区间\(\left(l,r\right]\)中存在\(n\)的倍数的充要条件是\(\left\lfloor\frac{r}{n}\right\rfloor>\left\lfloor\frac{l}{n}\right\rfloor\)。证明:记有整数\(k\)满足\(k\timesn\in\left(l,r\right]\)。那么有\[\displaystylel<k\timesn......
  • 【Solid works报错(无法连接到服务器)】
    报错有时,安装好SolidWorks后,打开时会弹出如下的错误弹窗原因最主要的原因之一为:安装的杀毒软件将SolidWorks服务设为禁止启动,每次开机后都需要进行手动的启动,这里以火绒为例。点击进入火绒之后,点击启动项管理,找到服务项中的SolidWorksFlexnetServer和SolidWorksLicens......
  • Jenkins Console 页中文显示乱码的问题
    背景:JenkinsServer为Helm安装,使用的是Bitnami的chart,当前app版本为Jenkins2.401.2添加一台Agent,该Agent的语言默认为zh_CN.UTF-8Pipeline使用docker的形式运行每个任务。表现形式:在Jenkins管理页面添加并配置Agent,使用SSH方式连接Agent,在连接日志界面有......
  • 达芬奇 DaVinci Resolve Studio 17.4影视后期调色软件下载和安装教程
    DaVinciResolve是一款专业的调色软件,将专业8K编辑,色彩校正,视觉效果和音频后期制作等功能集于一体的影视后期处理软件。广泛应用在影视后期,栏目包装,宣传片、广告片等领域。软件介绍调色页面设有全新HDR面板,可让您创建自定义色调范围的色轮,以便单独对任何色调范围进行微调!新增的......
  • idea实用插件推荐(1)-Grep Console
    1.简介GrepConsole可以根据日志等级设置不同的颜色,效果如下:安装点击File->Settings在搜索框里输入GrepConsole,点击install即可安装使用安装成功后,在idea控制台右键点击ShowGrepConsoleStatisticsinConsole,即可设置对应日志级别的颜色公众号:1号程序员,关注回复B0......
  • ZooKeeper(外部)实例 + SolrCloud(tomcat)实例
    Solr学习(三)单独ZooKeeper(外部)实例+SolrCloud(tomcat)实例博客分类: JavaSolrLucenesolr4.2.0ZooKeeperSolrSolrCloud 开场白:简单讲述如何配置独立的外部ZooKeeper集群管理组件来管理solr集群(多实例solr)本章建立在 Solr学习(一)  、Soer学习(二)基础上......