首页 > 其他分享 >NOIP2024加赛5

NOIP2024加赛5

时间:2024-11-15 18:00:14浏览次数:1  
标签:suf right 1000010 int ll 加赛 NOIP2024 left

NOIP2024加赛5

题目来源: 2023NOIP A层联测31

\(T1\) HZTG5777. 暴力操作(opt) \(40pts\)

  • 先将 \(\{ a \}\) 升序排序。

  • 因为 \(\left\lfloor \dfrac{\left\lfloor \frac{a}{b} \right\rfloor}{c} \right\rfloor=\left\lfloor \dfrac{a}{bc} \right\rfloor\) ,先钦定 \(\forall i,j \in \mathbb{N}^{*},c_{i,j} \le c_{i}+c_{j}\) ,并让每个数仅被操作一遍。

  • 考虑二分答案,并只对 \([1,\left\lceil \frac{n}{2} \right\rceil]\) 进行操作。

  • 此时需要解形如 \(\left\lfloor \frac{a_{i}}{x} \right\rfloor \le mid\) 的不等式,可以使用二分求解,也可以观察到 \(\frac{a_{i}}{x} < mid+1\) 从而得到 \(x \ge \left\lfloor \frac{a_{i}}{mid+1} \right\rfloor+1\) 。然后取 \(\min\limits_{k \in [\left\lfloor \frac{a_{i}}{mid+1} \right\rfloor+ \infty)}\{ c_{x} \}\) 加入代价。

  • 对于 \(\min\limits_{k \in [\left\lfloor \frac{a_{i}}{mid+1} \right\rfloor+ \infty)}\{ c_{x} \}\) 初始时仅通过调和级数处理到 \(m\) 是不够的。

  • 设 \(\{ suf \}\) 表示 \(\{ c \}\) 的后缀 \(\min\) 。不妨先处理出 \([1,m]\) 的后缀 \(\min\) ,此时有 \(suf_{m+1}=\min\limits_{i=1}^{m}\{ c_{i}+suf_{\left\lceil \frac{m+1}{i} \right\rceil} \}\) ,再次倒着更新 \([1,m+1]\) 的后缀 \(\min\) 即可。

    点击查看代码
    ll a[500010],c[500010],suf[500010];
    bool check(ll n,ll m,ll k,ll mid)
    {
        ll sum=0;
        for(ll i=1;i<=n/2+1;i++)
        {
            if(a[i]>mid)
            {
                sum+=suf[a[i]/(mid+1)+1];
            }
        }
        return sum<=k;
    }	
    int main()
    {
    #define Isaac
    #ifdef Isaac
        freopen("opt.in","r",stdin);
        freopen("opt.out","w",stdout);
    #endif	
        ll n,m,k,l=0,r,mid,ans=-1,i,j;
        scanf("%lld%lld%lld",&n,&m,&k);
        r=m;
        for(i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
        }
        for(i=1;i<=m;i++)
        {
            scanf("%lld",&c[i]);
        }
        sort(a+1,a+1+n);
        c[1]=0;
        for(i=1;i<=m;i++)
        {
            for(j=1;i*j<=m;j++)
            {
                c[i*j]=min(c[i*j],c[i]+c[j]);
            }
        }
        suf[m]=c[m];
        for(i=m-1;i>=1;i--)
        {
            suf[i]=min(suf[i+1],c[i]);
        }
        suf[m+1]=0x3f3f3f3f;
        for(i=1;i<=m;i++)
        {
            j=ceil(1.0*(m+1)/i);
            if(j<=m)
            {
                suf[m+1]=min(suf[m+1],c[i]+suf[j]);
            }
        }
        for(i=m;i>=1;i--)
        {
            suf[i]=min(suf[i+1],c[i]);
        }
        while(l<=r)
        {
            mid=(l+r)/2;
            if(check(n,m,k,mid)==true)
            {
                ans=mid;
                r=mid-1;
            }
            else
            {
                l=mid+1;
            }
        }
        printf("%lld\n",ans);
        return 0;
    } 
    

\(T2\) HZTG5778. 异或连通(xor) \(50pts\)

  • 部分分

    • 子任务 \(1\) :\(DFS\) 找连通块。
    • 子任务 \(2\) :加个记忆化即可。
    点击查看代码
    struct node
    {
        ll nxt,to,w;
    }e[200010];
    ll head[200010],vis[200010],siz,cnt=0;
    unordered_map<ll,ll>f;
    void add(ll u,ll v,ll w)
    {
        cnt++;
        e[cnt].nxt=head[u];
        e[cnt].to=v;
        e[cnt].w=w;
        head[u]=cnt;
    }
    void dfs(ll u,ll x,ll k)
    {
        siz++;
        vis[u]=1;
        for(int i=head[u];i!=0;i=e[i].nxt)
        {
            if(vis[e[i].to]==0&&(e[i].w^x)<k)
            {
                dfs(e[i].to,x,k);
            }
        }
    }
    int main()
    {
    #define Isaac
    #ifdef Isaac
        freopen("xor.in","r",stdin);
        freopen("xor.out","w",stdout);
    #endif	
        ll n,m,q,k,u,v,w,x,ans=0,i,j;
        scanf("%lld%lld%lld%lld",&n,&m,&q,&k);
        for(i=1;i<=m;i++)
        {
            scanf("%lld%lld%lld",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        for(j=1;j<=q;j++)
        {
            scanf("%lld",&x);
            if(f.find(x)==f.end())
            {
                ans=0;
                memset(vis,0,sizeof(vis));
                for(i=1;i<=n;i++)
                {
                    if(vis[i]==0)
                    {
                        siz=0;
                        dfs(i,x,k);
                        ans+=siz*(siz-1)/2;
                    }
                }
                f[x]=ans;
            }
            printf("%lld\n",f[x]);
        }
        return 0;
    }
    
  • 正解

    • 等学了线段树分治再来补。

\(T3\) HZTG5779. 诡异键盘(keyboard) \(20pts\)

  • 部分分

    • 子任务 \(1\) :哈希优化字符串匹配后跑 \(O(n^{3})\) 的 \(DP\) 。
    点击查看代码
    const ll mod=1000003579,base=13331;
    ll f[5010],hshs[5010],lent[5010],jc[5010];
    vector<ll>hsht[5010];
    char s[1000010];
    void sx_hash(char s[],ll len)
    {
        for(ll i=0;i<=len;i++)
        {
            hshs[i]=(i==0)?0:(hshs[i-1]*base%mod+s[i])%mod;
        }
    }
    void sx_hash_t(char s[],ll len,ll id)
    {
        for(ll i=0;i<=len;i++)
        {
            hsht[id][i]=(i==0)?0:(hsht[id][i-1]*base%mod+s[i])%mod;
        }
    }
    ll ask_hash(ll l,ll r)
    {
        return (hshs[r]-hshs[l-1]*jc[r-l+1]%mod+mod)%mod;
    }
    int main()
    {
    #define Isaac
    #ifdef Isaac
        freopen("keyboard.in","r",stdin);
        freopen("keyboard.out","w",stdout);
    #endif	
        int t,n,m,len,i,j,k,h;
        cin>>t;
        for(i=0;i<=5000;i++)
        {
            jc[i]=(i==0)?1:jc[i-1]*base%mod;
        }
        for(h=1;h<=t;h++)
        {
            memset(f,0x3f,sizeof(f));
            cin>>n>>m;
            for(i=1;i<=n;i++)
            {
                cin>>(s+1);
                lent[i]=strlen(s+1);
                hsht[i].clear();
                hsht[i].resize(lent[i]+10);
                sx_hash_t(s,lent[i],i);
            }
            cin>>(s+1);
            len=strlen(s+1);
            sx_hash(s,len);
            f[0]=0;
            for(i=1;i<=len;i++)
            {
                for(j=0;j<=i-1;j++)
                {
                    for(k=1;k<=n;k++)
                    {
                        if(i-j<=lent[k]&&ask_hash(j+1,i)==hsht[k][i-j])
                        {
                            f[i]=min(f[i],f[j]+lent[k]-(i-j)+1);
                        }
                    }
                }
            }
            cout<<((f[len]==0x3f3f3f3f3f3f3f3f)?1:f[len])<<endl;
        }
        return 0;
    }
    
  • 正解

\(T4\) HZTG5780. 民主投票(election) \(5pts\)

  • 部分分

    • 子任务 \(1\) :模拟。
    点击查看代码
    vector<int>e[1000010];
    int siz[1000010],dfn[1000010],out[1000010],pos[1000010],fa[1000010],sum[1000010],tot;
    void add(int u,int v)
    {
        e[u].push_back(v);
    }
    void dfs(int x)
    {
        siz[x]=1;
        tot++;
        dfn[x]=tot;
        pos[tot]=x;
        for(int i=0;i<e[x].size();i++)
        {
            dfs(e[x][i]);
            siz[x]+=siz[e[x][i]];
        }
        out[x]=tot;
    }
    bool work(int x,int maxx)
    {
        if(x==1)
        {
            return true;
        }
        x=fa[x];
        while(x!=0)
        {
            if(sum[x]+1<maxx)
            {
                sum[x]++;
                return true;
            }
            x=fa[x];
        }
        return false;
    }
    int check(int x,int n)
    {
        memset(sum,0,sizeof(sum));
        int maxx=siz[x]-1;
        for(int i=1;i<=n;i++)
        {
            if((i<=dfn[x]||i>out[x])&&work(pos[i],maxx)==false)
            {
                return 0;
            }
        }
        return 1;
    }
    int main()
    {
    #define Isaac
    #ifdef Isaac
        freopen("election.in","r",stdin);
        freopen("election.out","w",stdout);
    #endif	
        int t,n,i,j,k;
        scanf("%d",&t);
        for(k=1;k<=t;k++)
        {
            scanf("%d",&n);
            tot=0;
            for(i=1;i<=n;i++)
            {
                e[i].clear();
            }
            for(i=2;i<=n;i++)
            {
                scanf("%d",&fa[i]);
                add(fa[i],i);
            }
            dfs(1);
            for(i=1;i<=n;i++)
            {
                printf("%d",check(i,n));
            }
            printf("\n");
        }
        return 0;
    }
    
  • 正解

    • 等有时间再补。

总结

  • \(T1\) 调和级数仅处理到了 \(m\) ,挂了 \(60pts\) 。
  • \(T4\) 链的部分分写假了,挂了 \(20pts\) 。

后记

  • \(T1\) 题面从 \(tgHZOJ\) 搬过来的时候忘把更改后的题面(将原 \(x \in [1,m]\) 改成了 \(c_{x \in [1,m]}\))搬过来了,赛时 \(feifei\) 用画图更改了题面重新下发了。
  • \(T3\) 未注明 \(\sum|S_{i}|\) 为单组数据的数据规模。

标签:suf,right,1000010,int,ll,加赛,NOIP2024,left
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18548407

相关文章

  • NOIP2024模拟赛#21 总结
    坐牢3h+。赛时开T1,发现好唐啊,10min切了。过了全部大样例。开T2,现在是8:10。?现在是8:27,我怎么把T2大样例全过了。是不是太水了。我只是胡了一个贪心啊。开T3,现在是8:30。草,T1加样例了,做法假了。先不管T1了,先去看T3。感觉保证每次操作后都会满足对于\(i......
  • NOIP2024 前集训:MX 炼石计划 NOIP 模拟赛 20
    前言今天不知道为啥去打MX了,bug不少啊,包括但不限于赛时能通过自己主页看自己题过没过,赛时可以进入“补题”的比赛交从而直接成IOI赛制,文件还有点问题?0+100+12+0,T1读假题:\(\ge×,>√\),喜提爆零,但是本来就不会正解,我去我表都打出来了不知道二分??!?!!?不打T4是错误的,乱搞能得的分......
  • 【考试题解】NOIP2024(欢乐)加赛3
    目录A.SakurakoandWater题目内容思路代码B.BinomialCoefficients,KindOf题目内容思路代码C.QED'sFavoritePermutation题目内容思路代码D.CardGame题目内容思路代码E.LongWaytobeNon-decreasing题目内容思路代码F.ManyGames题目内容思路代码A.SakurakoandW......
  • NOIP2024模拟赛27 | 选手只有 T4 AC
    又是高一rk7。这场大众分太高了。我以为有很多人过T4的。80(95)+80+45(55)+100,sy机子太慢了。T1:场上只想出来\(A^{1/4}\log^2A\)的单次做法,只有80。即枚举小的那个底数。结论:满足条件的数可以表示成\(a^2b^3\)。???这样直接枚举\(\min(a,b)\le4000\)的质因子就做......
  • NOIP2024 前集训:NOIP2024加赛 3(欢乐赛)
    前言再次考古,现在才写。这场叫欢乐赛,搬的CF,不知道OJ哪儿来的RMJ。就记得T3一直往数据结构上想浪费好多时间,结果发现是结论题\(O(n)\)可做。T1SakurakoandWater虽然我之前不知道主对角线是什么东西,但是看完题目自动把他过滤成左上角到右下角了(不知道当时怎么想的,好......
  • NOIP2024 前集训:多校A层冲刺NOIP2024模拟赛20
    前言考古了,现在才写。已经忘了赛时历程了,就记得T1打了个错误率高达\(\dfrac{1}{100000}\)的乱搞做法(前后各连\(\log\)个\(k\)大值)然后被卡常了,后三道都没交不记得为啥了。T1星际联邦std是\(O(m\logm)\)的菠萝算法,但是被众人疯狂爆标。正解是\(O(n)\)的,不考虑......
  • 多校A层冲刺NOIP2024模拟赛21
    以为150要垫底了,没想到还有高手。送信卒签,没一会就写完但因为交的太晚被猫娘抢了首A。恼火。简要题意给一个\(n\timesm(n,m\le100)\)的网格图,左右走的代价为\(1\),上下走的代价为\(k\),求最小的\(k\),使得\((sx,sy)\)到\((tx,ty)\)的代价恰好为\(s(s\le10^5)\)。数据保证有解......
  • 『模拟赛』多校A层冲刺NOIP2024模拟赛21
    Rank别样的,不好评价,烂完了A.送信卒签,我是唐氏。为什么呢题目没给最短路的定义,我赛时觉得最短路就是最短路径,于是直接bfs一遍随便加个check就做完了。当然过得那遍按我的思路来说是错的,然后我也发现了这一点,然后就改了,然后就WA了。总结:错误思路的错解是正确思路......
  • 多校A层冲刺NOIP2024模拟赛21
    多校A层冲刺NOIP2024模拟赛21\(T1\)A.送信卒\(90pts/100pts\)部分分\(90pts\)设最后的可能的最短路中左右共移动了\(d\)次,上下共移动了\(x\)次。则等价于求\(\min\{x_{i}k+d_{i}\}=s\)的解,观察到\(d\in[0,\min(\left\lceil\frac{nm}{2}\right\rce......
  • NOIP2024模拟赛#18 总结
    头要炸了。T1题面很好懂,手玩了一下发现答案最小是\((m-1)\timesn\)。可能会多出来一个长度为\(k\)的部分,会发现如果多出来一个长度为\(k\)的部分且合法,那么单个串\(1\simk\)位与\(n-k+1\simn\)位一定相同,\(k+1\simn\)位与\(1\simn-k\)一定相同。Hash判一下即......