「ALFR Round 3」基础赛题D T472521 求救!!
  • 板块学术版
  • 楼主photony
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/12/21 21:45
  • 上次更新2024/12/22 09:59:31
查看原帖
「ALFR Round 3」基础赛题D T472521 求救!!
427390
photony楼主2024/12/21 21:45

比赛过程中以为模拟就能过www,结果花了很长时间也没有调出来。稍微解释一下自己的代码:

  • vector<long long> adj[]是一个记录中子来源的动态数组;
  • neu_0[]是记录从外面打进来的中子(也就是题干里指出的viv_i)的数组
  • last_neutron[] 是记录上一秒打进来的中子数的数组(因为这一秒的裂变仅仅依赖于上一秒和viv_i

同时,我注意到经过有限长的时间后体系一定会达到稳态,也就是我代码中写到的:

stable_boundary=i=1na[i]stable\_boundary=\sum_{i=1}^na[i]

在经过stable_boundary的时间后,所有可裂变的原子都开始裂变。因此在stable_boundary + 1k的时间内各个原子接收到的中子数亦不变,不必进行模拟,可直接用乘法计算。

理论上我的程序的复杂度应该在O(m+n+min(k,a[i])×(n+a[i]))\mathcal O\left(m + n + \min(k, \sum a[i]) \times \left(n + \sum a[i]\right)\right)。实际测试的时候Subtest 0全对,Subtest 1第一个点TLE,,第二个点AC,其余测试WA。

求助大佬 QAQQAQ~

#include<bits/stdc++.h>
using namespace std;
long long neutron[500001],a[500001],ans[500001],neu_0[500001];
int mod=998244353;
vector<long long> adj[500001];
long long n,k,m;
int main(){
    scanf("%lld %lld %lld",&n,&k,&m);
    if(m==0 or k==0){for(int i=1;i<=n;i++)printf("%lld ",0ll);return 0;}
    for(int i=0;i<m;i++){
        int tmp;
        scanf("%d",&tmp);
        neutron[tmp]++;
    }
    long long stable_boundary=0;
    memcpy(neu_0, neutron, sizeof(neutron));
    for(int i=1;i<=n;i++){
        int tmp;
        scanf("%lld",&a[i]);
        stable_boundary+=a[i];
        for(int j=0;j<a[i];j++){
            scanf("%d",&tmp);
            adj[tmp].push_back(i);
        }
    }
    for(long long i=1;i<=min(stable_boundary+1,k);i++){
        long long last_neutron[500001];
        memcpy(last_neutron, neutron, sizeof(neutron));
        bool stable=true;
        for(int j=1;j<=n;j++){
            neutron[j]=neu_0[j];
            for(auto h:adj[j]){
                if(last_neutron[h])neutron[j]++;
            }
            if(last_neutron[j])ans[j]=(ans[j]+(a[j]+last_neutron[j]))%mod;
            if(neutron[j]!=last_neutron[j])stable=false;
        }
        if(stable){
            long long remaining_time=k-i;
            for(int j=1;j<=n;j++)ans[j]=(ans[j]+(remaining_time*(a[j]+last_neutron[j]))%mod)%mod;
            break;
        }
    }
    for(int i=1;i<=n;i++)printf("%lld ",ans[i]);
    printf("\n");
    return 0;
}
2024/12/21 21:45
加载中...