codeforces Round 1070(Div. 2)

D https://codeforces.com/contest/2176/problem/D

哎哎,经典的赛后过题。分享D的另一种不同的思路。

Hint1 首先可以观察到除了单独一条边成斐波那契数列的情况,其它更长的数列情况中,除了作为开头的两个点,其它的点都是严格单调递增的。

根据这个这个观察我们可以把图上原来{u,v}(ta[u]<ta[v])的边删除。这样就变成有向无环图了。

再运用dfs回溯+dp(可以参考代码理解),最后再加上单独一条边成斐波那契数列的情况就可以了。

附上代码

复制代码
int n,m;cin>>n>>m;
int ans=m;
vvi g(n+1),g1(n+1);
vi din(n+1);
vi ta(n+1);
for (int i=1;i<=n;i++) cin>>ta[i];
for (int i=1;i<=m;i++)
{
    int u,v;cin>>u>>v;
    g[u].push_back(v);
}
for (int i=1;i<=n;i++)
{
    vi tc;
    for (auto v:g[i])
    {
        if(ta[v]>ta[i])
        {
            tc.push_back(v);
        }
        
    }
    g1[i]=g[i];
    g[i]=tc;
}
for (int i=1;i<=n;i++)
{
    auto tv=g[i];
    for (auto v:tv)
    {
        din[v]++;
    }
}
vi dp(n+1);
vi vis(n+1);
vector<map<int,int>> cnt(n+1);
auto dfs=[&](auto self,int u)->void
{
    vis[u]=1;
    // cout<<u<<endl;
    for (auto v:g[u])
    {
        din[v]--;
        if(vis[v]==0)
        self(self,v);
        cnt[u][ta[v]-ta[u]]=(cnt[u][ta[v]-ta[u]]+cnt[v][ta[u]]+1)%mod;
    }
};
for (int i=1;i<=n;i++)
{
    if(!din[i]&&vis[i]==0)
    {
        // cout<<i<<endl;
        dfs(dfs,i);
    }
}
for (int i=1;i<=n;i++)
{
    for (auto v:g1[i])
    {
        ans=(ans+cnt[v][ta[i]])%mod;
    }
    // cout<<i<<" "<<ans<<endl;
}
cout<<ans<<endl;
相关推荐
Timmylyx051820 天前
CF 新年赛 Goodbye 2025 题解
算法·codeforces·比赛日记
Timmylyx051820 天前
2025年最后一搏—— Educational Codeforces Round 186 (Rated for Div. 2) 题解
算法·codeforces·比赛日记
defaulter3 个月前
Codeforces Round 1049 (Div. 2)C. Ultimate Value
算法·codeforces
图灵信徒5 个月前
ICPC Central Russia Regional Contest, 2024
c++·python·codeforces·算法竞赛
超闻逸事6 个月前
题解:CF2129C Interactive RBS
c++·算法·codeforces
ReineRabbit6 个月前
重生之 CF2126G2. Big Wins! (hard version)
线段树·codeforces·中位数
Savior`L6 个月前
Educational Codeforces Round 181 (Rated for Div. 2)
数据结构·c++·算法·codeforces
TL自动机6 个月前
Educational Codeforces Round 180 (Rated for Div. 2) C. Coloring Game
codeforces
Closet1237 个月前
Codeforces 2025/6/11 日志
c++·算法·codeforces