HDU 6155 Subsequence Count(矩阵乘法+线段树+基础DP)

本文介绍了一种利用线段树和矩阵乘法解决01串区间操作问题的方法,通过定义状态转移矩阵和使用线段树维护区间信息,实现了高效地翻转区间和查询不同子序列数量的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意

给定一个长度为 n01 串,完成 m 种操作——操作分两种翻转 [l,r] 区间中的元素、求区间 [l,r] 有多少个不同的子序列。

1n,m105

思路

看到这种题目,应该条件反射的去想一下线段树。

但首先还是从一个询问开始,对于一个长度为 n 的串,设 dpi,j 为前 i 位组成的序列中,以 j 结尾的串的个数,若串的第 i 位为 j 有递推式:

dpi,j=dpi1,0+dpi1,1+1

dpi,!j=dpi1,!j

上式是以 0j,1j 结尾的串的个数,加上单独一个j ;下式则直接转移上一位的信息。

那么将 {dp0,0,dp0,1,1} 作为初始矩阵,用线段树维护区间对应的转移矩阵即可。

代码

  1. #include<bits/stdc++.h>
  2. #define FOR(i,x,y) for(int i=(x),i##END=(y);i<=i##END;++i)
  3. #define DOR(i,x,y) for(int i=(x),i##END=(y);i>=i##END;--i)
  4. typedef long long LL;
  5. using namespace std;
  6. const int N=1e5+5;
  7. const int P=1e9+7;
  8. struct Matrix
  9. {
  10. int n,m,a[4][4];
  11. int *operator [](const int x){return a[x];}
  12. void resize(int _n,int _m){n=_n,m=_m;}
  13. Matrix operator *(const Matrix &_)const
  14. {
  15. Matrix res;res.resize(n,_.m);
  16. FOR(i,1,n)FOR(j,1,_.m)
  17. {
  18. res[i][j]=0;
  19. FOR(k,1,m)(res[i][j]+=1ll*a[i][k]*_.a[k][j]%P)%=P;
  20. }
  21. return res;
  22. }
  23. void flip()
  24. {
  25. swap(a[1][1],a[2][2]);
  26. swap(a[1][2],a[2][1]);
  27. swap(a[3][1],a[3][2]);
  28. }
  29. Matrix operator *=(const Matrix &_){return (*this)=(*this)*_;}
  30. };
  31. const Matrix Zero=(Matrix){
  32. 3,3,
  33. 0,0,0,0,
  34. 0,1,0,0,
  35. 0,1,1,0,
  36. 0,1,0,1};
  37. const Matrix One =(Matrix){
  38. 3,3,
  39. 0,0,0,0,
  40. 0,1,1,0,
  41. 0,0,1,0,
  42. 0,0,1,1};
  43. Matrix nd[N<<2],A;
  44. int tag[N<<2];
  45. char str[N];
  46. void build(int k,int l,int r)
  47. {
  48. tag[k]=0;
  49. if(l==r)
  50. {
  51. if(str[l]=='0')nd[k]=Zero;
  52. else nd[k]=One;
  53. return;
  54. }
  55. int mid=(l+r)>>1;
  56. build(k<<1,l,mid);
  57. build(k<<1|1,mid+1,r);
  58. nd[k]=nd[k<<1]*nd[k<<1|1];
  59. }
  60. void push_down(int k)
  61. {
  62. if(!tag[k])return;
  63. tag[k<<1]^=1,nd[k<<1].flip();
  64. tag[k<<1|1]^=1,nd[k<<1|1].flip();
  65. tag[k]=0;
  66. }
  67. void update(int k,int L,int R,int l,int r)
  68. {
  69. if(L<=l&&r<=R)
  70. {
  71. tag[k]^=1,nd[k].flip();
  72. return;
  73. }
  74. push_down(k);
  75. int mid=(l+r)>>1;
  76. if(L<=mid)update(k<<1,L,R,l,mid);
  77. if(R>mid)update(k<<1|1,L,R,mid+1,r);
  78. nd[k]=nd[k<<1]*nd[k<<1|1];
  79. }
  80. Matrix query(int k,int L,int R,int l,int r)
  81. {
  82. if(L<=l&&r<=R)return nd[k];
  83. push_down(k);
  84. int mid=(l+r)>>1;
  85. if(R<=mid)return query(k<<1,L,R,l,mid);
  86. else if(L>mid)return query(k<<1|1,L,R,mid+1,r);
  87. else return query(k<<1,L,R,l,mid)*query(k<<1|1,L,R,mid+1,r);
  88. }
  89. int main()
  90. {
  91. A.resize(1,3);
  92. A[1][1]=0,A[1][2]=0,A[1][3]=1;
  93. int T,n,Q;
  94. scanf("%d",&T);
  95. while(T--)
  96. {
  97. scanf("%d%d",&n,&Q);
  98. scanf("%s",str+1);
  99. build(1,1,n);
  100. int op,x,y;
  101. while(Q--)
  102. {
  103. scanf("%d%d%d",&op,&x,&y);
  104. if(op==1)update(1,x,y,1,n);
  105. else
  106. {
  107. Matrix res=A*query(1,x,y,1,n);
  108. printf("%d\n",(res[1][1]+res[1][2])%P);
  109. }
  110. }
  111. }
  112. return 0;
  113. }

转载于:https://www.cnblogs.com/Paulliant/p/10189068.html

内容概要:本文详细介绍了机器学习的基础知识、流程及应用。首先概述了机器学习的定义、分类(监督学习、无监督学习、强化学习)及其在金融、医疗、自动驾驶等领域的应用实例。接着阐述了数据准备和预处理阶段的关键步骤,包括数据采集、清洗和转换。然后探讨了如何选择合适的机器学习模型,如决策树、支持向量机、神经网络等,并强调了根据问题类型、数据特性、模型复杂度和计算资源等因素选择模型的重要性。此外,文章还讲解了模型训练和评估的方法,包括训练集和测试集的划分、参数调整和优化策略、常用评估指标等。最后讨论了模型优化和调参的技术,如超参数调整、模型融合、特征选择,以及模型部署到生产环境的方法和监控模型表现的策略。 适合人群:对机器学习感兴趣的学习者、初学者以及有一定经验的数据科学家和技术人员。 使用场景及目标:①帮助读者理解机器学习的基本概念、流程和应用场景;②指导读者完成从数据准备到模型部署的整个机器学习项目;③提高读者在实践中选择、训练、评估和优化机器学习模型的能力。 阅读建议:本文内容全面覆盖了机器学习的各个关键环节,适合系统性学习。读者应结合实际案例进行练习,特别是在数据处理、模型选择和调参方面,多动手实践以加深理解和掌握技能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他
点击体验
DeepSeekR1满血版
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回顶部

登录后您可以享受以下权益:

×