QOJ.ac

QOJ

ID提交记录ID题目HackerOwner结果提交时间测评时间
#1073#678949#9527. A Brand New Geometric Problemhos_lyricucup-team3161Success!2024-10-27 16:25:552024-10-27 16:25:56

详细

Extra Test:

Time Limit Exceeded

input:

100000 9340531200 9340531200
85229 170458 255687 340916 426145 511374 596603 681832 767061 852290 937519 1022748 1107977 1193206 1278435 1363664 1448893 1534122 1619351 1704580 1789809 1875038 1960267 2045496 2130725 2215954 2301183 2386412 2471641 2556870 2642099 2727328 2812557 2897786 2983015 306...

output:


result:


ID题目提交者结果用时内存语言文件大小提交时间测评时间
#678949#9527. A Brand New Geometric Problemucup-team3161#TL 833ms69736kbC++172.1kb2024-10-26 16:30:222024-11-06 13:15:58

answer

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lll __int128
#define eb emplace_back
const int N=3e3+5;
const ll INF=1e18;
int n,tp;ll m,c,s,ans=INF,d[N];
vector<int> vc[N];
unordered_map<ll,ll> cnt,dp[N];
bool chk(ll x) {return (lll)x*x*x<=m;}
int id(ll x) {return lower_bound(d+1,d+tp+1,x)-d;}
void W(int x,ll y,ll w)
{
    if(y>c) return;
    if(!dp[x].count(y)) dp[x][y]=w;
    else dp[x][y]=min(dp[x][y],w);
}
int main()
{
    scanf("%d %lld %lld",&n,&c,&m);
    for(int i=1;i<=n;++i) {ll x;scanf("%lld",&x);++cnt[x];}
    for(int i=1;1ll*i*i<=m;++i) if(!(m%i))
    {
        d[++tp]=i;
        if(1ll*i*i<m) d[++tp]=m/i;
    }
    dp[1][0]=0;
    sort(d+1,d+tp+1);
    for(int i=tp,x;i;--i)
        if(d[i]>1 && chk(d[i]))
        {
            x=cnt[d[i]];
            for(int j=tp;j;--j)
            {
                ll t1=m/d[j];
                for(auto &[k,w]:dp[j])
                {
                    ll t=1;
                    for(int l=1;;++l)
                    {
                        t=1ll*t*d[i];
                        if(t1%t) break;
                        W(id(d[j]*t),k+l*d[i],w+abs(x-l));
                    }
                    w+=x;
                }
            }
        }
    for(auto [x,w]:cnt) if(x>1 && (m%x || !chk(x))) s+=w;
    int x=cnt[1];
    for(int i=1;i<=tp;++i) for(int j=1;j<i;++j)
        if(!(d[i]%d[j]) && !chk(d[j]) && !chk(d[i]/d[j])) vc[i].eb(d[j]);
    for(int i=1;i<=tp;++i)
    {
        for(auto [j,w]:dp[i])
        {
            ll t=m/d[i];
            if(d[i]==m && j<=c) ans=min(ans,w+s+abs(c-j-x));
            if(chk(t)) continue;
            if(j+t<=c) ans=min(ans,w+s+abs(c-j-t-x)+(cnt[t]?-1:1));
            for(auto k:vc[id(t)])
            {
                ll l=t/k;
                if(j+k+l>c) continue;
                if(k==l) ans=min(ans,w+s+abs(c-j-k-l-x)-cnt[k]+abs(cnt[k]-2));
                else ans=min(ans,w+s+abs(c-j-k-l-x)+(cnt[k]?-1:1)+(cnt[l]?-1:1));
            }
        }
    }
    printf("%lld\n",ans<INF?ans:-1);return 0;
}