刚刚结束的比赛 E 题部分分求条,悬 2 关

学术版

kele7 @ 2024-10-05 19:26:49

rt, 赛时打的是 1\le c\le 4\times 10^6 的部分分,然后爆零了。

我的构造方法是让 a_1=0,a_2=1,然后 a_i(i>2)=a_{i-1}a_i(i>1)=a_{i-1}+1,容易发现这时 \text{mex} 的区间和就是 \sum (a_i+1),具体就是先找到这个序列的最短长度 k,然后直接在 0,1,2\ldots k-3,k-2 里面插入一个数就构造好了,但是必须 a_2\ne 0,所以改成 0,1,1,2,3\ldots k-5,k-4,k-3,k-3 即可。

拍没拍出来 /kk

#include<bits/stdc++.h>
#define int long long
using namespace std;
int T,n,k,c;
signed main(){
    cin>>T;
    while(T--){
        cin>>n;
        if(!n){//特判
            cout<<"1\n1\n";
            continue;
        }
        if(n==1){
            cout<<"1\n0\n";
            continue;
        }
        if(n==2){
            cout<<"2\n0 2";
            continue;
        }
        if(n==4){
            cout<<"4\n0 2 2 2\n";
            continue;
        }
        int k=(int)sqrt(n*2);//找最短长度,这里写的有点抽象,勿喷 QwQ
        if((k-2)*(k-1)>=2*n)k=k-2;
        else if((k-1)*k>=2*n)k=k-1;
        else if(k*(k+1)>=2*n)k=k;
        else if((k+1)*(k+2)>=2*n)k=k+1;
        else if((k+2)*(k+3)>=2*n)k=k+2;
        n-=(k-1)*k/2;c=-1;//先有 0,1,2...k-2 然后插一个数进去
        if(n==1){//特判 a2=0,这时对序列进行微小调整
            cout<<k<<"\n";
            cout<<"0 1 1 ";
            for(int i=4;i<k;i++){
                cout<<i-2<<" ";
            }cout<<k-3<<"\n";
            continue;
        }
        cout<<k<<"\n";
        for(int i=1;i<=k;i++){
            if(c==n-1){
                cout<<c<<" ";
                n=-1;
            }
            else cout<<++c<<" ";
        }cout<<"\n";
    }
}

by kele7 @ 2024-10-05 19:28:02

题目链接


by WeWantToRun @ 2024-10-05 19:29:45

您写的好复杂!您可以参考一下我写的:

void solve(){
  int c;read(c);
  if(c==0){puts("1\n1");return;}
  std::vector<int>ans;
  int cur=0;
  while(1){
    if(c<=cur)break;
    ans.pb(cur);
    ++cur;
    c-=cur;
  }
  if(c>1)ans.pb(c-1);
  std::sort(ans.begin(),ans.end());
  if(c==1){
    print(ans.size()+1,'\n');
    for(int i:ans){
      if(i==0)print(i,' '),print(100000,' ');
      else print(i,' ');
    }
    puts("");
    return;
  }
  print(ans.size(),'\n');
  for(int i:ans)print(i,' ');
  puts("");
}

by kele7 @ 2024-10-05 19:37:43

@WeWantToRun 能不能说一下怎么构造的


by WeWantToRun @ 2024-10-05 19:40:57

就是 0 1 2 3 4 ... 下去

完了如果多出来一个 c,那就中间扔一个 c-1 进去

如果多出来一个 1,那就第二位放个 inf 进去


by kele7 @ 2024-10-05 21:50:19

哦哦哦


by zhouyixuan11 @ 2024-10-06 08:59:44

@kele7 tql


|