2019南京赛
Posted hgangang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019南京赛相关的知识,希望对你有一定的参考价值。
hello 2019;题意:
给出区间,要你在查询区间内有9102,同时没有8012的序列,需要删除多少个数字。
多次询问,所以给上我们的线段树。
这道题有原题;
我们dp表示i从状态i到状态j的操作次数,
我们定义0,1,2,3,4为"",2,20,201,2017的状态。对于每个状态用矩阵表示:
如dp【1】【2】从状态为2到20;
例如我们看其中一个地方
if(s[l]==‘2‘) p[cur].a[0][0]=1,p[cur].a[0][1]=0;
表示此刻遇到了2,那么就0状态的“”到“”,要花费1
为什么呢,也就是我们“”遇到2,应变为2,但是你想保持“",那么就得删掉2,其他同理,
然后就来到但是到6的时候,保持201到201需要删除6,花费价值为1。因为不能出现2016,所以从2017转移也需要删除一个价值。
代码给上:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxx=2e5+100;
struct node
int a[5][5];
node operator+(const node &b)const//重载加法
node c;
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
c.a[i][j]=inf;
for(int k=0;k<5;k++)
c.a[i][j]=min(c.a[i][j],a[i][k]+b.a[k][j]);
return c;
p[maxx<<2];
char s[maxx];
int n,m;
inline void pushup(int cur)
p[cur]=p[cur<<1]+p[cur<<1|1];
inline void build(int l,int r,int cur)
if(l==r)
for(int i=0;i<5;i++)for(int j=0;j<5;j++) p[cur].a[i][j]=(i==j)?0:inf;
if(s[l]==‘2‘) p[cur].a[0][0]=1,p[cur].a[0][1]=0;
else if(s[l]==‘0‘) p[cur].a[1][1]=1,p[cur].a[1][2]=0;
else if(s[l]==‘1‘) p[cur].a[2][2]=1,p[cur].a[2][3]=0;
else if(s[l]==‘7‘) p[cur].a[3][3]=1,p[cur].a[3][4]=0;
else if(s[l]==‘6‘) p[cur].a[3][3]=1,p[cur].a[4][4]=1;
return ;
int mid=l+r>>1;
build(l,mid,cur<<1);
build(mid+1,r,cur<<1|1);
pushup(cur);
inline node query(int L,int R,int l,int r,int cur)
if(l<=L&&R<=r) return p[cur];
int mid=L+R>>1;
if(r<=mid) return query(L,mid,l,r,cur<<1);
else if(l>mid) return query(mid+1,R,l,r,cur<<1|1);
else return query(L,mid,l,mid,cur<<1)+query(mid+1,R,mid+1,r,cur<<1|1);
int main()
int l,r;
while(~scanf("%d%d",&n,&m))
scanf("%s",s+1);
build(1,n,1);
while(m--)
scanf("%d%d",&l,&r);
node ans=query(1,n,l,r,1);
if(ans.a[0][4]==inf) printf("-1\n");
else printf("%d\n",ans.a[0][4]);
return 0;
然后2019这道题就洒洒水地将序列反转变成找2019,不要2018,所以他给出区间后,你也得反转一下再询问,
代码如下:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxx=2e5+100;
struct node
int a[5][5];
node operator+(const node &b)const
node c;
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
c.a[i][j]=inf;
for(int k=0;k<5;k++)
c.a[i][j]=min(c.a[i][j],a[i][k]+b.a[k][j]);
return c;
p[maxx<<2];
char s[maxx],ss[maxx];
int n,m;
inline void pushup(int cur)
p[cur]=p[cur<<1]+p[cur<<1|1];
inline void build(int l,int r,int cur)
if(l==r)
for(int i=0;i<5;i++)for(int j=0;j<5;j++) p[cur].a[i][j]=(i==j)?0:inf;
if(s[l]==‘2‘) p[cur].a[0][0]=1,p[cur].a[0][1]=0;
else if(s[l]==‘0‘) p[cur].a[1][1]=1,p[cur].a[1][2]=0;
else if(s[l]==‘1‘) p[cur].a[2][2]=1,p[cur].a[2][3]=0;
else if(s[l]==‘9‘) p[cur].a[3][3]=1,p[cur].a[3][4]=0;
else if(s[l]==‘8‘) p[cur].a[3][3]=1,p[cur].a[4][4]=1;
return ;
int mid=l+r>>1;
build(l,mid,cur<<1);
build(mid+1,r,cur<<1|1);
pushup(cur);
inline node query(int L,int R,int l,int r,int cur)
if(l<=L&&R<=r) return p[cur];
int mid=L+R>>1;
if(r<=mid) return query(L,mid,l,r,cur<<1);
else if(l>mid) return query(mid+1,R,l,r,cur<<1|1);
else return query(L,mid,l,mid,cur<<1)+query(mid+1,R,mid+1,r,cur<<1|1);
int main()
int l,r;
while(~scanf("%d%d",&n,&m))
scanf("%s",ss+1);
for(int i=1;i<=n;i++) s[i]=ss[n-i+1];
build(1,n,1);
while(m--)
scanf("%d%d",&l,&r);
node ans=query(1,n,n-r+1,n-l+1,1);
if(ans.a[0][4]==inf) printf("-1\n");
else printf("%d\n",ans.a[0][4]);
return 0;
//感谢大佬地博客:https://blog.csdn.net/starlet_kiss/article/details/100694910
以上是关于2019南京赛的主要内容,如果未能解决你的问题,请参考以下文章
2019ICPC南京网络赛A题 The beautiful values of the palace(三维偏序)