传送门

给出一个数字字串,给出若干个询问,询问在字串的一段区间保证出现2017" role="presentation" style="position: relative;">20172017而不出现2016" role="presentation" style="position: relative;">20162016需要删去的最少字符。

下面定义5个状态。

状态0:连2都没有

状态1:只有2,没有0连在后面

状态2:出现20,没有1连在后面

状态3:出现201,没有7连在后面

状态4:出现2017

这样每次询问时,用f[i][j]" role="presentation" style="position: relative;">f[i][j]f[i][j]表示从状态i" role="presentation" style="position: relative;">ii转移到状态j" role="presentation" style="position: relative;">jj所需的最小费用,不难发现这个东西是可以进行合并的,因此可以使用线段树来维护。

但要注意6的处理情况,显然6的出现只会影响到状态3和状态4,所以简单更新一下就可以了。

代码如下:

  1. #include<bits/stdc++.h>
  2. #define N 200005
  3. #define inf 0x3f3f3f3f
  4. #define lc (p<<1)
  5. #define rc (p<<1|1)
  6. #define mid (T[p].l+T[p].r>>1)
  7. using namespace std;
  8. inline int min(int a,int b){return a<b?a:b;}
  9. struct Node{
  10. int l,r,f[5][5];
  11. inline void create(int x){
  12. for(int i=0;i<=4;++i)
  13. for(int j=0;j<=4;++j)
  14. f[i][j]=(i==j?0:inf);
  15. switch(x){
  16. case -1:{for(int i=0;i<=4;++i)f[i][i]=inf;break;}
  17. case 2:{f[0][0]=1,f[0][1]=0;break;}
  18. case 0:{f[1][1]=1,f[1][2]=0;break;}
  19. case 1:{f[2][2]=1,f[2][3]=0;break;}
  20. case 7:{f[3][3]=1,f[3][4]=0;break;}
  21. case 6:{f[3][3]=1,f[4][4]=1;break;}
  22. }
  23. }
  24. }T[N<<2];
  25. int n,m,num[N];
  26. char s[N];
  27. inline Node merge(Node a,Node b){
  28. Node ret;
  29. ret.create(-1);
  30. ret.l=a.l,ret.r=b.r;
  31. for(int i=0;i<=4;++i)
  32. for(int j=0;j<=4;++j)
  33. for(int k=0;k<=4;++k)
  34. ret.f[i][j]=min(ret.f[i][j],a.f[i][k]+b.f[k][j]);
  35. return ret;
  36. }
  37. inline void build(int p,int l,int r){
  38. T[p].l=l,T[p].r=r;
  39. if(l==r){T[p].create(num[l]);return;}
  40. build(lc,l,mid),build(rc,mid+1,r);
  41. T[p]=merge(T[lc],T[rc]);
  42. }
  43. inline Node query(int p,int ql,int qr){
  44. if(ql<=T[p].l&&T[p].r<=qr)return T[p];
  45. if(qr<=mid)return query(lc,ql,qr);
  46. if(ql>mid)return query(rc,ql,qr);
  47. return merge(query(lc,ql,mid),query(rc,mid+1,qr));
  48. }
  49. int main(){
  50. scanf("%d%d%s",&n,&m,s+1);
  51. for(int i=1;i<=n;++i)num[i]=s[i]-'0';
  52. build(1,1,n);
  53. while(m--){
  54. int l,r;
  55. scanf("%d%d",&l,&r);
  56. Node ans=query(1,l,r);
  57. printf("%d\n",ans.f[0][4]==inf?-1:ans.f[0][4]);
  58. }
  59. return 0;
  60. }

2018.07.22 codeforces750E(线段树维护状态转移)的更多相关文章

  1. Codeforces750E. New Year and Old Subsequence (线段树维护DP)

    题意:长为2e5的数字串 每次询问一个区间 求删掉最少几个字符使得区间有2017子序列 没有2016子序列 不合法输出-1 题解:dp i,p(0-4)表示第i个数匹配到2017的p位置删掉的最少数 ...

  2. Wannafly挑战赛22 D 整数序列 (线段树维护三角函数值)

    链接:https://ac.nowcoder.com/acm/contest/160/D 来源:牛客网 整数序列 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语 ...

  3. Codeforces GYM 100114 D. Selection 线段树维护DP

    D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...

  4. [BZOJ 3995] [SDOI2015] 道路修建 【线段树维护连通性】

    题目链接:BZOJ - 3995 题目分析 这道题..是我悲伤的回忆.. 线段树维护连通性,与 BZOJ-1018 类似,然而我省选之前并没有做过  1018,即使它在 ProblemSet 的第一页 ...

  5. CodeForces 343D 线段树维护dfs序

    给定一棵树,初始时树为空 操作1,往某个结点注水,那么该结点的子树都注满了水 操作2,将某个结点的水放空,那么该结点的父亲的水也就放空了 操作3,询问某个点是否有水 我们将树进行dfs, 生成in[u ...

  6. Codeforces 834D The Bakery【dp+线段树维护+lazy】

    D. The Bakery time limit per test:2.5 seconds memory limit per test:256 megabytes input:standard inp ...

  7. 洛谷P4243/bzoj1558 [JSOI2009]等差数列(线段树维护差分+爆炸恶心的合并)

    题面 首先感谢这篇题解,是思路来源 看到等差数列,就会想到差分,又有区间加,很容易想到线段树维护差分.再注意点细节,\(A\)操作完美解决 然后就是爆炸恶心的\(B\)操作,之前看一堆题解的解释都不怎 ...

  8. hdu 5068 线段树维护矩阵乘积

    http://acm.hdu.edu.cn/showproblem.php?pid=5068 题意给的略不清晰 m个询问:从i层去j层的方法数(求连段乘积)或者修改从x层y门和x+1层z门的状态反转( ...

  9. bzoj 2124 等差子序列 (线段树维护hash)

    2124: 等差子序列 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 1922  Solved: 714[Submit][Status][Discuss ...

随机推荐

  1. nginx 域名绑定

    单个域名 upstream web{ server ;//这里绑定你要访问的服务器地址 keepalive ; } server { listen ; server_name www.xxxx.con ...

  2. Maven 多环境 打包

    1.pom.xml文件添加profiles属性 <profiles> <profile> <id>dev</id> <activation> ...

  3. jdk免安装对应配置

    通常我们不用配置jdk,tomcat和eclipse会选取系统的环境变量获取jdk,但有时一个系统中部署不同的项目,各版本又不一样,不能完全兼容. 因此就需要采用自己的jdk.将jdk安装后,将安装后 ...

  4. 使用webstorm创建vue项目

    进行vue开发首先需要配置node环境 配置好node环境在命令行中输入node -v npm -v则表示环境配置成功 在webstorm命令行中输入命令 1.安装脚手架 npm install -g ...

  5. Mysql日期时间Extract函数介绍

    MySQL日期时间Extract函数的优点在于可以选取日期时间的各个部分,从年一直到微秒,让我们对MySQL日期时间的处理更为轻松. MySQL 日期时间 Extract(选取)函数.1. 选取日期时 ...

  6. 两个关于URL解析的例子

    例一: /* 解析URL查寻串中的name=value参数对 将name=value对存储在对象属性中,并返回对象 alert(getQuery().name) */ function getQuer ...

  7. 解决Linux命令行为什么变成-bash-3.2$

    在Linux服务器上创建了一个新用户probe,是这样创建的: [root@localhost home]# groupadd -g 501 probe [root@localhost home]# ...

  8. 第三方苹果开发库之ASIHTTPRequest

    转载于:http://www.dreamingwish.com/dream-2011/apples-third-party-development-libraries-asihttprequest.h ...

  9. c# 结构体 集合 复习

    添加5个学生的信息到集合中,每个学生都有:学号,姓名,成绩,3个内容,添加完毕后将学生的分数从高到低排列并打印出来,使用结构体 using System; using System.Collectio ...

  10. tomcat发布webservice

    编写后台代码: package test; import javax.jws.WebParam; import javax.jws.WebService; @WebService public cla ...