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南京赛的主要内容,如果未能解决你的问题,请参考以下文章

super_log (广义欧拉降幂)(2019南京网络赛)

2019ICPC南京网络赛A题 The beautiful values of the palace(三维偏序)

ICPC2019 亚洲区域赛 南京站

2019icpc南京网络赛 A 主席树

2019ACM-ICPC南京网络赛Holy Grail (SPFA模板题)

[欧拉降幂][2019南京网络赛B]super_log