codeforces Round 1070(Div. 2)

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

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

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

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

再运用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;
相关推荐
所以遗憾是什么呢?1 个月前
【题解】Codeforces Round 1097 (Div. 2, Based on Zhili Cup 2026) (致理杯) ABCDEF
数据结构·算法·acm·codeforces·icpc·ccpc·xcpc
wenhaoran112 个月前
CF1800F Dasha and Nightmares
c++·算法·字符串·codeforces·位运算
超闻逸事4 个月前
题解:CF2196D Double Bracket Sequence
codeforces
Timmylyx05185 个月前
Codeforces Round 1075 (Div. 2) 题解
算法·codeforces·比赛日记
Timmylyx05185 个月前
CF 新年赛 Goodbye 2025 题解
算法·codeforces·比赛日记
Timmylyx05185 个月前
2025年最后一搏—— Educational Codeforces Round 186 (Rated for Div. 2) 题解
算法·codeforces·比赛日记
defaulter8 个月前
Codeforces Round 1049 (Div. 2)C. Ultimate Value
算法·codeforces
图灵信徒9 个月前
ICPC Central Russia Regional Contest, 2024
c++·python·codeforces·算法竞赛
超闻逸事10 个月前
题解:CF2129C Interactive RBS
c++·算法·codeforces