DTOJ#5029. shot

要怎样才能将我的心

映在镜中让你看清

即使是场终成奢望的爱恋

是否也有映在镜中的一天

在马群中,大马的久久注视着小马。

那快乐的神态,曼妙的身材和矫健的步伐已经深深印在大马的心里。

在长久的犹豫之后,大马决定用自己优秀的射击技巧得到小马的注目。

射击场上有 n n n 只气球排成一排,大马会进行 m m m 次射击。

为了展现自己的射击技巧,大马每次会请小马选定一个气球 x i x_i xi,如果第 x i x_i xi 个气球没有被打破,就会打破第 x i x_i xi 个气球,否则,大马会随机选择左边或右边第一个没有被打破的气球进行射击(如果一边已经没有气球了,大马一定会射击另一边的气球)。

但是,小马的目光并没有投向大马。它在思考:如果大马每次射击都保证击中,最后气球有多少种可能的被打破的状态呢?

大马的心在滴血。它决定请你帮它回答这个问题。

两种状态不同,当且仅当一个气球在一个状态中被打破,在另一个状态中没有被打破.

答案模 998244353 998244353 998244353 输出。

第一行两个整数 n , m n, m n,m

第二行, m m m 个整数,第 i i i 个整数为 x i x_i xi
一行一个整数,表示最终可能的状态数。

样例输入 1

6 4
2 3 4 4 

样例输出 1

2

样例 2

见选手文件下的 shot2.inshot2.ans

a i a_i ai 为第 i i i 个气球被选中的次数.

对于 $ 20% $ 的数据, n , m ≤ 20 n,m\leq20 n,m20

对于 40 % 40\% 40% 的数据,$ n, m \leq300$。

对于 60 % 60 \% 60% 的数据, n , m ≤ 5000 n, m\leq5000 n,m5000

对于另 10 % 10\% 10% 的数据,只存在最多一个整数 i i i 满足 a i > 1 a_i > 1 ai>1

对于 100 % 100\% 100% 的数据, n , m ≤ 1000000 n, m \leq1000000 n,m1000000

简单题,看出答案是分割后直接DP

#include<bits/stdc++.h>
#define N 1000005
using namespace std;
const int mod=998244353;
inline int read(){
    
    
	int x=0,f=1;char s=getchar();
	while(s<'0'||s>'9'){
    
    if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){
    
    x=(x<<3)+(x<<1)+s-'0';s=getchar();}
	return x*f;
}
int a[N],tmp[N<<1],f[N],sum[N];
inline int get(int x){
    
    
	int now=sum[x]-x+1;now+=N;
	return tmp[now];
}
inline void add(int x){
    
    
	int now=sum[x]-x;now+=N;
	tmp[now]=(tmp[now]+f[x])%mod;
}
int main(){
    
    
//	freopen("shot.in","r",stdin);
//	freopen("shot.out","w",stdout);
	int n=read(),m=read();
	for(int i=1;i<=m;++i)a[read()]++;
	for(int i=1;i<=n+1;++i)sum[i]=sum[i-1]+a[i];
	f[0]=1;add(0);
	for(int i=1;i<=n+1;++i){
    
    
		if(a[i])continue;
		f[i]=(f[i]+get(i))%mod;
		add(i);
		//if(sum[i]-sum[i-1]!=
	}
	printf("%d\n",(f[n+1]+mod)%mod);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/CSDNzhanghongyu/article/details/109524358