3 条题解

  • 2
    @ 2024-9-28 21:32:07

    思路

    貌似跟官方题解不一样?

    我们考虑最优情况下,对答案造成贡献的数会被我们放在什么位置。

    发现下标为 mm 的倍数能够“控制”的数是最多的,所以我们考虑将数填入下标为 mm 的倍数的地方。

    接下来我们来考虑答案。不难发现 nn 一定是对答案有贡献的;其次 nn 最多只能完全“控制” m1m-1 个数。

    这就意味着我们可以枚举 [nm,n)[n-m,n) 中的每一个值,将其作为可能的第二小的有贡献的数,计算其与 nngcd\gcdmax\max 即可。

    然后对于剩余的没有填的空位,降序将剩余的数填入即可。

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define sc second
    #define pii pair<int,int>
    #define pb push_back
    #define umap unordered_map
    #define mset multiset
    #define pq priority_queue
    #define ull unsigned long long
    #define i128 __int128
    const int maxn=1e6+10;
    int n,m,a[maxn],vis[maxn];
    void solve(){
        cin>>n>>m;
        int maxx=0,maxi=0;
        for(int i=1;i<=m;i++) if(maxx<__gcd(n,n-i)) maxi=n-i,maxx=__gcd(n,i);
        int num=n;
        for(int i=m;i<=n;i+=m) a[i]=num,vis[num]=1,num-=maxx;
        vector<int> vec;
        for(int i=n;i;i--) if(!vis[i]) vec.pb(i);
        int z=0;
        for(int i=1;i<=n;i++) if(!a[i]) a[i]=vec[z++];
        for(int i=1;i<=n;i++) cout<<a[i]<<" ",a[i]=vis[i]=0;
        cout<<endl;
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0),cout.tie(0);
        int t=1;
        cin>>t;
        while(t--) solve();
        return 0;
    }
    

    信息

    ID
    69
    时间
    3000ms
    内存
    512MiB
    难度
    5
    标签
    递交数
    446
    已通过
    92
    上传者