首页 > 其他分享 >P10218 [省选联考 2024] 魔法手杖 题解

P10218 [省选联考 2024] 魔法手杖 题解

时间:2024-07-03 19:33:11浏览次数:19  
标签:ch pw 省选 题解 ll int le ans 联考

题目描述:

给定序列 \(a_1,\cdots,a_n\) 和 \(b_1,\cdots,b_n\) ,满足 \(a_i\in [0,2^k-1],b_i\ge 0\),你需要给出 \(S\subseteq \{1,\cdots,n\}\) 和 \(x\in [0,2^k-1]\) 满足:

  • \(\sum\limits_{i\in S}b_i\le m\)。
  • 最大化 \(val(S,x)=\min\big(\min\limits_{i\in S}(a_i+x),\min\limits_{i\not\in S}(a_i\oplus x)\big)\)。

求 \(val(S,x)\) 的最大值。


数据范围:

  • \(1\le n\le 10^5,1\le\sum n\le 5\cdot 10^5\)。
  • \(0\le m,b_i\le 10^9\)。
  • \(0\le k\le 120\)。

时间限制 \(\texttt{1.5s}\),空间限制 \(\texttt{1024MB}\) 。


分析:

特判掉 \(\sum_{i=1}^nb_i\le m\) 的情况,此时 \(ans=\min\limits_{1\le i\le n}a_i+2^k-1\) 。

看到异或直接往 \(\texttt{trie}\) 树上想,考虑从高到低确定 \(x\) 和 \(ans\) 的每一位。

在 \(\texttt{trie}\) 树上递归时,我们已经考虑当前节点子树外的所有状态,并且正在考虑当前节点深度 \(d\) 的决策

如果 \(ans\) 第 \(d\) 位取 \(1\) ,那么左右子树中至少有一棵为空或者全部放入 \(S\) 中

如果 \(ans\) 第 \(d\) 位取 \(0\),那么与 \(x\) 当前位取值相反的子树一定取不到最小值,直接不予考虑。

递归时枚举 \(x\) 当前位取 \(0\) 还是 \(1\) 即可。

时间复杂度 \(\mathcal O(\sum nk)\)。

#include<bits/stdc++.h>
#define ll __int128
using namespace std;
const int maxn=1e5+5,maxm=1.2e7+5;
int k,m,n,tot;
int ch[maxm][2];
ll res,a[maxn],b[maxn],pw[125],v1[maxm],v2[maxm];
ll read()
{
    ll q=0;char ch=getchar();
    while(!isdigit(ch)) ch=getchar();
    while(isdigit(ch)) q=10*q+ch-'0',ch=getchar();
    return q;
}
void write(ll x)
{
    if(x>=10) write(x/10);
    putchar(x%10+'0');
}
void dfs(int p,int d,ll amin,ll bsum,ll x,ll ans)
{
    if(!~d) return res=max(res,ans),void();
    if(!p) return res=max(res,amin+x+pw[d+1]-1),void();
    int flg=0,lc=ch[p][0],rc=ch[p][1];
    ///x=0,ans=1
    if(bsum+v2[lc]<=m&&min(amin,v1[lc])+x+pw[d]-1>=ans+pw[d])
        flg=1,dfs(rc,d-1,min(amin,v1[lc]),bsum+v2[lc],x,ans+pw[d]);
    ///x=1,ans=1
    if(bsum+v2[rc]<=m&&min(amin,v1[rc])+x+pw[d+1]-1>=ans+pw[d])
        flg=1,dfs(lc,d-1,min(amin,v1[rc]),bsum+v2[rc],x+pw[d],ans+pw[d]);
    if(flg) return ;
    ///x=0,ans=0
    dfs(lc,d-1,amin,bsum,x,ans);
    ///x=1,ans=0
    dfs(rc,d-1,amin,bsum,x+pw[d],ans);
}
int main()
{
    for(int i=0;i<125;i++) pw[i]=i?pw[i-1]<<1:1;
    v1[0]=pw[120];
    for(int c=read(),t=read();t--;)
    {
        n=read(),m=read(),k=read();
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1;i<=n;i++) b[i]=read();
        memset(ch+1,0,8*tot),memset(v2+1,0,16*tot),v1[tot=1]=pw[k];
        for(int i=1;i<=n;i++)
            for(int j=k-1,p=1;;j--)
            {
                v1[p]=min(v1[p],a[i]),v2[p]+=b[i];
                if(!~j) break;
                int v=a[i]>>j&1;
                if(!ch[p][v]) v1[ch[p][v]=++tot]=pw[k];
                p=ch[p][v];
            }
        if(v2[1]<=m) res=v1[1]+pw[k]-1;
        else res=0,dfs(1,k-1,pw[k],0,0,res);
        write(res),putchar('\n');
    }
    return 0;
}

总结:

  • 和 \(\texttt{trie}\) 树有关的最优化问题一般会用到贪心的思想,笔者独立思考的时候跟着特殊性质 \(\texttt{A,B}\) 走到 \(\texttt{dp}\) 的坑里就爬不出来了。

标签:ch,pw,省选,题解,ll,int,le,ans,联考
From: https://www.cnblogs.com/peiwenjun/p/18282424

相关文章

  • 蓝桥 第 3 场 算法季度赛 前5题题解,剩下的后续发上去补上
    第1题全国科普行动日【算法赛】题目传送门直接输出就行,没多大操作可言:#include<iostream>usingnamespacestd;intmain(){cout<<"6.29";return0;}第2题 A%B【算法赛】题目传送门题目有点小坑,因为也可能是负数,所以需要特判一下,上代码就可以看懂了:#include......
  • YC309A [ 20240627 CQYC省选模拟赛 T1 ] 或(or)
    题意给定一个可重集\(S\),求所有的前缀的集合的代价。定义一个集合的代价为:\[\max_x\left((\max_ib_i\lvertx)-(\min_ib_i\lvertx)\right)\]\(n\le10^6,V\le2\times10^6\)Sol首先看到这个式子直接开划。称较大的数为\(b_i\),较小的数为\(b_j\)。直......
  • 流固耦合可能遇到的问题解决办法
    (纯私人经验)双向流固耦合中出现的一些问题及解决方法:1.出现负网格,可以加密网格,可以去提升网格质量,六面体网格尽量用icemcfd画,四面体就用自带的完全可以,可以增加刚度降低变形量从而消除负网格,可以调整弹簧光顺参数,一般经验取值一个0.6一个0.5,可以缩小时间步长,还可以在fluent......
  • 洛谷 P5723 【深基4.例13】质数口袋 题解
    题面传送门观察题目,我们可以看到这是一道朴素的,判断质数的一道题目。何为质数?质数就是除了111和这个本身,没有其他因数的数。特别的,......
  • AT_arc180_a [ARC180A] ABA and BAB 题解
    思路首先一个浅显易得的结论,当\(A\)或\(B\)连续出现时,我们可以将它们分成两段,每段都可以看作一个独立事件,结果数只和每个独立事件的样本点有关。我们设独立事件共有\(tot\)个,每个独立事件的样本点为\(w_i\),则显然有\(ans=\prod_{i=1}^{tot}w_i\)。接下来该找\(w_i\)......
  • 题解 - 数字计数
    题目思路简析正解是数位dp,但是我不太会,所以我打分块。考虑从\(10^6\)到\(2\times10^6\)和从\(3\times10^6\)到\(4\times10^6\),其中真正的区别只有观察到数据范围是\(10^{12}\),分为一些块,每块长\(10^6\)会比较均衡,所以共有\(10^6\)个块。最差情况是\(n=10^6+1......
  • 题解 - 数字计数
    题目思路简析正解是数位dp,但是我不太会,所以我打分块。考虑从\(10^6\)到\(2\times10^6\)和从\(3\times10^6\)到\(4\times10^6\),其中真正的区别只有观察到数据范围是\(10^{12}\),分为一些块,每块长\(10^6\)会比较均衡,所以共有\(10^6\)个块。最差情况是\(n=10^6+1......
  • 07/02/2024 融合热身赛赛后总结&题解
    一、总体情况考试一共有五道题。这次考试失误严重,C题非常水的一道题做了快两个小时,严重影响了心态和做其它题的时间。最终3个小时只做了A,C......
  • [JLU] 数据结构与算法上机题解思路分享-第三次上机
    前言首先,请务必自己尽全力尝试实现题目,直接看成品代码,思维就被拘束了,也很容易被查重。这里只是思路解析的博客,代码仓库在JLU_Data_Structures_Record希望你能在这里找到你想要的:)正文A图的创建分数10作者朱允刚单位吉林大学请编写程序创建一个有向图。有向图中包含......
  • YC307B [ 20240625 CQYC省选模拟赛 T2 ] 一个题(ynoi)
    题意你需要维护一个可重集\(S\),支持插入删除以及查询最大的方案使得给定正整数\(k\),划分为\(k\)个非空子集的按位与结果之和最大。\(n\le10^5\)Sol先上个trie。然后考虑一次查询怎么搞。先转化一下,如果需要划分为\(k\)个子集,显然需要合并\(n-k\)次。我们只......