每一年都奔走在自己热爱里

没有人是一座孤岛,总有谁爱着你

AtCoder Beginner Contest 247(E,F)

AtCoder Beginner Contest 247(E,F)

E(思维)

E

这个题大意就是给一个长度为n的数组,一个x和一个y,问这个数组里面可以找到多少段[l,r]满足这一段里面的最大值是x,最小值是y

这里的做法是固定最右端,寻找最左端的可能的数量,最后相加

对于每一个位置,都有作为最右端的可能,那么对于一个点i,我们可以去寻找这个最左端的范围

对于这一个范围的最左端就是离i最近的一个不满足条件的位置(大于最大值或者是小于最小值),最右端就是从1i以来,我们最后一次找到最大值的位置和最小值的位置的较小的那一个(这样从min(posx,posy)i,至少存在一个最大值和最小值)

只要存在满足这个范围的最左端,我们就加上去res=res+rl

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <bitset>
#include <unordered_map>
using namespace std;
const int maxn=2e5+10;
const int mod=998244353;
const double eps=1e-12;
#define int long long 
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
signed main ()
{
    int ans=0;
    int n,x,y;
    cin>>n>>x>>y;
    int pre=0;
    int posx=0,posy=0;
    for (int i=1;i<=n;i++)
    {
        int now;
        cin>>now;
        if(now>x||now<y) pre=i;
        if(now==x) posx=i;
        if(now==y) posy=i;
        int r=min(posx,posy);
        if(r>pre)
        {
            ans+=r-pre;
        }
    }
    cout<<ans<<"\n";
    system ("pause");
    return 0;
}

F(dp)

F

这个题的大意就是有n张牌,每一张牌都有两个数pqP=1,2,3,...n,Q=1,2,3,...n.

我们需要选择任意张牌,只要这些牌里面的数存在1n的数即可,问有多少种选择,可以满足以上条件

对于一张牌,可能存在两个不同的数,可以把两个数连在一起,我们把这些连在一次的那些数,我们可以把这些数看做一个整体,因为这些数字都存在两个,所以我们允许某些数只出现一个,所以我们要进行一次dp

dp[i][1][1]//对于i个数,dp[i][1][0]和dp[i][0][1]只存在一个
//对于只有一个数,只存在dp[1][1][1]=1,dp[1][0][0]=1,1个数在一张牌上
    dp[1][1][1]=1,dp[1][0][0]=1;
for (int i=2;i<=n;i++)
{
    for (int j=0;j<=1;j++)
    {
        dp[i][j][0]=dp[i-1][j][1];//这一个如果不选择,就需要依靠另外一张牌上的这一个数了
        dp[i][j][1]=(dp[i-1][j][0]+dp[i-1][j][1])%mod;//选择的话,上一张有和没有都没有什么关系,都可以
    }
    ans[i]=(dp[i][0][1]+dp[i][1][0]+dp[i][1][1])%mod;//保证前i个都存在
}

对于每一种环,都会包括cnt个数,那么这cnt个数需要ans[cnt]种选择可以让这cnt个数都存在

对于每一部分,用乘法计算

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <bitset>
#include <unordered_map>
using namespace std;
const int maxn=2e5+10;
const int mod= 998244353;
const double eps=1e-12;
#define int long long 
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
int n,p[maxn],q[maxn];
int f[maxn];
int siz[maxn];
int ans[maxn];
int dp[maxn][2][2];
int find(int x)
{
    if(x==f[x]) return f[x];
    return f[x]=find(f[x]);
}
void merge(int x,int y)
{
    int tx=find(x);
    int ty=find(y);
    if(tx==ty) return ;
    siz[tx]+=siz[ty];
    siz[ty]=0;
    f[ty]=tx;
    return ;
}
void init()
{
    dp[1][1][1]=1;
    dp[1][0][0]=1;
    ans[1]=1;
    for (int i=2;i<=n;i++)
    {
        for (int j=0;j<=1;j++)
        {
            dp[i][j][0]=dp[i-1][j][1];
            dp[i][j][1]=(dp[i-1][j][1]+dp[i-1][j][0])%mod;
        }
        ans[i]=(dp[i][1][1]+dp[i][1][0]+dp[i][0][1])%mod;
    }
    return ;
}
signed main ()
{
    cin>>n;
    init();
    for (int i=1;i<=n;i++)
    {
        f[i]=i;
        siz[i]=1;
        cin>>p[i];
    }
    for (int i=1;i<=n;i++)
    {
        cin>>q[i];
        merge(p[i],q[i]);
    }
    int res=1;
    for (int i=1;i<=n;i++)
    {
        if(find(i)==i)
        {
           // cout<<siz[i]<<"\n";
            res=(res*ans[siz[i]])%mod;
        }
    }
    cout<<res<<"\n";
    system ("pause");
    return 0;
}
posted @   righting  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示