ARC 128D - Neq Neq (dp + combinatorics + thinking)

Link

Title:

Given you a sequence of length n, you can operate on it to change the sequence. How many are there?

  • For consecutive i-1, i, i+1, if these three numbers satisfy ai − 1 ! = ai a_{i-1}!=a_{i}ai1!=aiAi ! = Ai + 1 a_ {i}! = a_ {i + 1}ai!=ai+1Then we can convert ai a_iaidelete.

analyze:

It is obvious to use DP to solve combinatorial math problems.
Then we think that the iiThe i position indicates the number of dp[i] solutions to i.
So will he transfer from that state to that?
First of all, dp[i] inherits dp[i-1], which is certain, and secondly, he can also delete the previous element to see if i-2, i-1, i meet the conditions mentioned above, then dp[i]+=dp[i-2],
and in addition to the previous one, we also want to know to delete one or more of the previous ones, then we can use prefix maintenance, but the prefix is ​​maintained until the same number appears at the same time.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define x first
#define y second
#define sf scanf
#define pf printf
#define PI acos(-1)
#define inf 0x3f3f3f3f
#define lowbit(x) ((-x)&x)
#define mem(a,x) memset(a,x,sizeof(a))
#define rep(i,n) for(int i=0;i<(n);++i)
#define repi(i,a,b) for(int i=int(a);i<=(b);++i)
#define repr(i,b,a) for(int i=int(b);i>=(a);--i)
#define debug(x) cout << #x << ": " << x << endl;

const int MOD = 998244353;
const int mod = 1e9 + 7;
const int MAX = 2e5 + 10;
const int dx[] = {
    
    0, 1, -1, 0, 0};
const int dy[] = {
    
    0, 0, 0, 1, -1};
const int dz[] = {
    
    1, -1, 0, 0, 0, 0 };
int day[] = {
    
    0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};


void init()
{
    
    

}
ll qpow(ll a, ll b, ll p)
{
    
    
    ll ans = 1;
    while(b)
    {
    
    
        if(b & 1) ans = ans * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return ans;
}


string str;
ll n,m,s;
ll a[MAX],dp[MAX],b[MAX],sum[MAX];
void solve()
{
    
    
    cin>>n;
    dp[0]=1;
    ll j=0,num=0,k=1;
    for(int i=1;i<=n;i++){
    
    
        cin>> a[i];
        dp[i]=dp[i-1];/// 继承上一状态
        if(a[i]==a[i-1]) j= i-1;///上一个 一对相等的位置,
        if(i>2&&a[i]!=a[i-1]&&a[i-1]!=a[i-2])///满足条件
        {
    
    
            dp[i]=(dp[i]+dp[i-2])%MOD;
        }
        if(b[a[i]]==0) num++;///来了一个新元素
        b[a[i]]++;
        while(k<i-2 && num>=3){
    
    
            b[a[k]]--;
            if(b[a[k]]==0)num--;
            k++;
        }
        if(j<k) dp[i]+=sum[k-1]-sum[j];
        dp[i]=(dp[i]%MOD+MOD)%MOD;
        sum[i]=(sum[i-1]+dp[i])%MOD;
    }
    cout<<dp[n]<<endl;

}

int main()
{
    
    
    init();
    ll t = 1;
    ///scanf("%lld", &t);
    while(t--)
    {
    
    
        solve();
    }
    return 0;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326265919&siteId=291194637
arc