列表

详情


NC204555. 区间加

描述

牛牛给牛妹出了到简单区间加题,牛妹觉得太简单于是稍微修改了一下。

牛妹有个长为的序列。每次牛妹会选择这个序列中的一段区间进行区间加,但是要满足的条件:对于任意两次区间加的起始,结束位置各不相同。

现在牛妹问你存在多少种区间加方式使得最后得到的序列使得,由于方案数过多,答案对取模。

输入描述

第一行两个整数表示序列的长度以及任意的目标值。
接下来个整数,为牛妹的初始序列。

输出描述

一个整数表示方案数,答案对取模。

示例1

输入:

3 2
1 1 1

输出:

4

说明:

存在一下四种分法{[(l,r)}表示{[l,r]}这个区间里面加{1]}:
{(1,3)}
{(1,2)(3,3)}
{(1,1)(2,3)}
{(1,1)(2,2)(3,3)}

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 4ms, 内存消耗: 504K, 提交时间: 2020-04-08 00:25:29

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244355;
ll a[2005],b[2005];
int main(){
    ios::sync_with_stdio(0);
    int n,m;cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i],a[i]=m-a[i],b[i]=a[i]-a[i-1];
    ll ans=1,now=0;
    for(int i=1;i<=n;i++){
        if(abs(b[i]>1)) return cout<<0,0;
        if(b[i]==1) ++now;
        if(b[i]==-1) (ans*=now)%=mod,now--;
        if(b[i]==0) (ans*=(now+1))%=mod;
    }
    cout<<ans<<endl;
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 5ms, 内存消耗: 492K, 提交时间: 2020-04-04 20:17:20

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=998244355;
ll n,m,tmp,ans=1,a[2005],b[2005];
int main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%lld",a+i);
		b[i]=m-a[i];
	}
	for(int i=1;i<=n;i++){
		if(abs(b[i]-b[i-1])>1){printf("0\n");return 0;}
		if(b[i]-b[i-1]==1) tmp++;
		else if(b[i]-b[i-1]==-1) ans=ans*tmp%mod,tmp--;
		else ans=ans*(tmp+1)%mod;
	}
	printf("%lld",ans);
}

上一题