1 条题解

  • 1
    @ 2025-10-8 21:46:20

    题解看不懂,不会归并🤪🤪 O(n2klogk)O(n^2k\log k)

    首先套路的将aia_{i}从小到大排序,将求权值改为数 ai+1aia_{i+1}-a_{i}的个数,不难注意到设计dpdp式子为 fi,j,kf_{i,j,k}到第ii个数,分为jj个集合,首尾确定了kk个,手玩发现从i+1i+1转移到ii权值变化永远是(ai+1ai)(2jk)(a_{i+1}-a_{i})*(2*j-k)其实就是在每个集合的的自由端添数,后填的数一定比现在大,为了计算后面的距离所以要加上(ai+1ai)(2jk)(a_{i+1}-a_{i})*(2*j-k)。 然后就简单了,分类讨论一下是否创建新集合,是否合并集合,是否作为首尾,自己模拟一下即可。码风亲民易看懂

    #include<bits/stdc++.h>
    #include<unistd.h>
    #include<bits/extc++.h>
    //#define getchar my_gechar
    #define ll long long
    #define lll __int128
    #define db double
    #define ldb long double
    #define pb emplace_back
    #define fi first
    #define se second
    #define mp make_pair
    #define pii pair<int,int> 
    #define vec Point
    #define fill0(a) memset(a,0,sizeof(a))
    #define fill1(a) memset(a,-1,sizeof(a))
    #define fillbig(a) memset(a,63,sizeof(a))
    // #define max(a,b) ((a)<(b)?(b):(a))
    // #define min(a,b) ((a)<(b)?(a):(b))
    #define vi vector<int> 
    #define vl vector<ll>
    #define lowbit(x) (x)&(-x)
    //#define sort stable_sort
    using namespace std;
    using namespace __gnu_pbds;
    char buffer[32769];
    unsigned li = 0;
    inline char my_gechar(){
        if(buffer[li] == '\0') buffer[read(0, buffer, 32768)] = '\0',li = 0;
        return buffer[li++];
    }
    namespace ly
    {
        namespace IO
        {
            #ifndef LOCAL
                constexpr auto maxn=1<<20;
                char in[maxn],out[maxn],*p1=in,*p2=in,*p3=out;
    
                #define flush() (fwrite(out,1,p3-out,stdout))
                #define putchar(x) (p3==out+maxn&&(flush(),p3=out),*p3++=(x))
                class Flush{public:~Flush(){flush();}}_;
            #endif
            namespace usr
            {
                template<typename type>
                      inline type read(type &x)
                {
                    x=0;bool flag(0);char ch=getchar();
                    while(!isdigit(ch)) flag^=ch=='-',ch=getchar();
                    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
                    return flag?x=-x:x;
                }
                template<typename type>
                inline void write(type x)
                {
                    x<0?x=-x,putchar('-'):0;
                    static short Stack[50],top(0);
                    do Stack[++top]=x%10,x/=10;while(x);
                    while(top) putchar(Stack[top--]|48);
                }
                inline int read(double &x){return scanf("%lf",&x);}
                inline int read(long double &x){return scanf("%Lf",&x);}
                inline void dwrite(const double &x,int y=6,bool flag=1){printf("%.*lf",y,x),flag?putchar(' '):putchar(' ');}
                inline void dwrite(const long double &x,int y=6,bool flag=1){printf("%.*Lf",y,x),flag?putchar(' '):putchar(' ');}
                inline char read(char &x){do x=getchar();while(isspace(x));return x;}
                inline char write(const char &x){return putchar(x);}
                inline void read(char *x){static char ch;read(ch);do *(x++)=ch;while(!isspace(ch=getchar())&&~ch);}
                inline void write(const char *x){while(*x)putchar(*(x++));}
                inline void read(string &x){char ch[1000005]={};read(ch),x=ch;}
                inline void write(const string &x){int len=x.length();for(int i=0;i<len;++i)putchar(x[i]);}
                template<typename type,typename...T>
                inline void read(type &x,T&...y){read(x),read(y...);}
                template<typename type,typename...T>
                inline void write(const type &x,const T&...y){write(x),putchar(' '),write(y...),sizeof...(y)^1?0:putchar(' ');}
                inline __int128 read(){static __int128 x;return read(x);}
                template<typename type>
                inline type put(type x,bool flag=1){write(x),flag?putchar(' '):putchar(' ');return x;}
            }
            #ifndef LOCAL
                #undef getchar
                #undef flush
                #undef putchar
            #endif
        }using namespace IO::usr;
    }using namespace ly::IO::usr;
    struct Point{
        int x,y;
        Point operator +(const Point& b)const{return {x+b.x,y+b.y};}
        Point operator -(const Point& b)const{return {x-b.x,y-b.y};}
        bool operator <(const Point& b)const{
            if(x!=b.x)return x<b.x;
            return y<b.y;
        }
    };
    const int N=1e5+5;
    const int M=1e6+5;
    const int inf=1e9+5;
    const int mod=1e9+7;
    const int bit=50;
    //mt19937 sj(chrono::steady_clock::now().time_since_epoch().count());
    int B=705;
    int n,m;
    int a[N];
    struct node{
        ll val;
        ll cnt;
        bool operator < (const node &b) const{
            return val>b.val;
        }
    };
    struct G{
        node a[105];
        int cnt=0;
        inline void init() { cnt=0;}
        inline void new_node(ll x,ll y){
            a[++cnt]={x,y};
        }
        inline void work(){
            sort(a+1,a+cnt+1);
            int tot=0;
            ll sum=0;
            for(int i=1,pos;i<=cnt;i=pos){
                sum=0;
                pos=i;
                while(pos<=cnt&&a[pos].val==a[i].val) (sum+=a[pos++].cnt)%=mod;
                a[++tot]={a[i].val,sum};
                if(tot>=m) break;
            }
            cnt=min(tot,m);
        }
    }f[3][2][605];
    inline void solve(){
        read(n,m);
        for(int i=1;i<=n;++i) read(a[i]);
        sort(a+1,a+n+1);
        f[0][1][1].new_node(0ll,1ll);
        f[1][1][1].new_node(0ll,2ll);
        int now=0;
        for(int i=n-1;i>=1;--i){
            now^=1;
            for(int j=1;j<=n;++j){
                for(int k=0;k<3;++k){
                    if(f[k][now][j].cnt){
                        f[k][now][j].work();
                        for(int t=1;t<=f[k][now][j].cnt;++t){
                            ll val=f[k][now][j].a[t].val+(a[i+1]-a[i])*(2*j-k);
                            ll num=f[k][now][j].a[t].cnt;
                            if(j-k+1>0) f[k][now^1][j+1].new_node(val,num*(j-k+1)%mod);
                            if(2-k>0) f[k+1][now^1][j+1].new_node(val,num*(2-k)%mod);
                            if(j-1>0) f[k][now^1][j-1].new_node(val,num*(j-1)%mod);
                            if(2*j-k>0) f[k][now^1][j].new_node(val,num*(2*j-k)%mod);
                            if(2-k>0) f[k+1][now^1][j].new_node(val,num*(2-k)%mod);
                        }
                        f[k][now][j].init();
                    }
                }
            }
        }
        now^=1;
        f[2][now][1].work();
        int i=1;
        for(;i<=min(m,f[2][now][1].cnt);++i){
            write(f[2][now][1].a[i].val,f[2][now][1].a[i].cnt);
            puts("");
        }
        for(;i<=m;++i){
            write(-1,-1);
            puts("");
        }
    }
    
    signed main()
    {   
        int _=1;
        while(_--) solve();
        return (0-0);
    }
    
    
    
    • 1

    信息

    ID
    3855
    时间
    1000ms
    内存
    256MiB
    难度
    9
    标签
    (无)
    递交数
    25
    已通过
    3
    上传者