暑假集训CSP提高模拟18

暑假集训CSP提高模拟18

组题人: @H_Kaguya | @joke3579

\(T1\) P227. Mortis \(0pts\)

  • 原题: [ABC302G] Sort from 1 to 4 | luogu P1459 [USACO2.1] 三值的排序 Sorting a Three-Valued Sequence

  • 部分分

    • \(0pts\) :输出逆序对个数。
  • 正解

    • \(\{ a \}\) 排序后的序列为 \(\{ b \}\)
    • 然后大力分讨。
      • \(a_{i}=b_{i}\) 说明不需要进行交换。
      • 否则,若存在 \(i \ne j\) 使得 \(a_{i}=b_{j},a_{j}=b_{i}\) 交换两者即可,对答案产生 \(1\) 的贡献。
      • 再否则,若存在 \(i \ne j \ne k\) 使得 \(a_{i}=b_{j},a_{j}=b_{k},a_{k}=b_{i}\) ,顺序交换三者即可,对答案产生 \(2\) 的贡献。
      • 再否则,剩下的数一定形如 \(a_{i}=b_{j},a_{j}=b_{k},a_{k}=b_{h},a_{h}=b_{i}(i \ne j \ne k \ne h)\) ,顺序交换四者即可,对答案产生 \(3\) 的贡献。
    • 具体地,我们记录 \(c_{i,j}\) 表示 \(i\) 最终位置上 \(j\) 的个数。不对情况 \(1\) 进行统计,仅枚举情况 \(2,3\) ,剩下的就是情况 \(4\) 的贡献。
    点击查看代码
    int a[200010],b[200010],c[5][5];
    int main()
    {int n,ans=0,sum=0,i,j,k;cin>>n;for(i=1;i<=n;i++){cin>>a[i];b[i]=a[i];}sort(b+1,b+1+n);for(i=1;i<=n;i++){if(b[i]!=a[i]){sum++;c[b[i]][a[i]]++;}}for(i=1;i<=4;i++){for(j=1;j<=4;j++){if(i!=j){while(c[i][j]>=1&&c[j][i]>=1){ans++;sum-=2;c[i][j]--;c[j][i]--;}}}}for(i=1;i<=4;i++){for(j=1;j<=4;j++){for(k=1;k<=4;k++){if(i!=j&&i!=k&&j!=k){while(c[i][j]>=1&&c[j][k]>=1&&c[k][i]>=1){ans+=2;sum-=3;c[i][j]--;c[j][k]--;c[k][i]--;}}}}}cout<<ans+sum/4*3<<endl;return 0;
    }
    

\(T2\) P228. 生活在hzoi上 \(0pts\)

  • 原题: luogu P5206 [WC2019] 数树 问题 \(1\)
  • 部分分
    • \(5pts\) :每个节点仅能给 \(1\) ,生成树的方案数为 \(n^{n-2}\)
  • 正解
    • 逆天题面, \(miaomiao\) 说改不动就不用改了。上次遇到子集反演的时候 \(miaomiao\) 就直接毙了。
    • 挂一下官方题解。

    题面锅了,谢罪。

    首先我们先考虑一个暴力。枚举第二棵树的形态求方案。

    先给他转化一下,容易发现只在一棵树里出现的边是没用的,那么考虑两棵树内都存在的边。而根据定义,如果只保留两棵树内都存在的边,那同一联通块内的节点给的数是一样的。

    那么设 \(E_1\) 为第一棵树的边集,\(E_2\) 为第二棵树的边集,总方案数就是 \(y^{n-|E_1\cap E_2|}\)

    然后考虑正解。现在答案是这个东西:

    \[\sum_{E_2}y^{n-|E_1\cap E_2|} \]

    有个憨批式子叫子集反演:

    \[f(S)=\sum_{T\subseteq S}\sum_{P\subseteq T}(-1)^{|T|-|P|}f(P) \]

    那设个 \(f(S)=y^{n-|S|}\) 推式子:

    \[\begin{aligned} &\sum_{E_2}y^{n-|E_1\cap E_2|}\\ =&\sum_{E_2}f(E_1\cap E_2)\\ =&\sum_{E_2}\sum_{T\subseteq E_1\cap E_2}\sum_{P\subseteq T}(-1)^{|T|-|P|}f(P)\\ =&\sum_{E_2}\sum_{T\subseteq E_1\cap E_2}\sum_{P\subseteq T}(-1)^{|T|-|P|}y^{n-|P|}\\ =&\sum_{E_2}\sum_{T\subseteq E_1\cap E_2}y^{n-|T|}\sum_{P\subseteq T}(-y)^{|T|-|P|}\\ =&\sum_{E_2}\sum_{T\subseteq E_1\cap E_2}y^{n-|T|}\sum_{i=0}^{|T|}\binom{|T|}i(-y)^{|T|-i}\\ =&\sum_{E_2}\sum_{T\subseteq E_1\cap E_2}y^{n-|T|}(1-y)^{|T|}\\ =&\sum_{T\subseteq E_1}y^{n-|T|}(1-y)^{|T|}g(T) \end{aligned} \]

    其中 \(g(T)\) 为包含边集 \(T\) 的树个数。由 prufer 序列容易得到

    \[g(T)=n^{k-2}\prod_{i=1}^ka_i \]

    其中 \(k\) 是连通块个数(也就是 \(n-|T|\)), \(a_i\) 是第 \(i\) 个连通块大小。

    那么代回原式:

    \[\begin{aligned} &\sum_{T\subseteq E_1}y^{n-|T|}(1-y)^{|T|}g(T)\\ =&\sum_{T\subseteq E_1}y^k(1-y)^{n-k}n^{k-2}\prod_{i=1}^ka_i\\ =&\frac{(1-y)^n}{n^2}\sum_{T\subseteq E_1}\prod_{i=1}^k\frac{ny}> {1-y}a_i \end{aligned} \]

    先特判掉 \(y=1\)

    考虑一下怎么算后边一堆东西。设个 \(dp_{x,i}\)\(x\) 的子树内 \(x\) 所在连通块大小为 \(i\) 的答案,转移考虑在 \(x\) 处枚举子树 \(v\)\((x,v)\) 这条边选不选。这样树上背包就是 \(O(n^2)\) 的。

    考虑优化。我们 \(dp\) 的瓶颈为第二维枚举联通块的大小,其实有个 trick 可以给他压掉:考虑到扩展Cayley定理里的式子 \(\prod_{i=1}^ka_i\) 的意义,是每个连通块里面选一个标记点连上,把联通块的贡献变成在联通块内选一个标记点的贡献,即每个联通块有且仅有一个标记点。如果选了标记点那么产生了一个有贡献的联通块,贡献要乘上 \(\dfrac ny{1-y}\)

    那么设 \(dp_{x,0/1}\)\(x\) 子树内 \(x\) 所在联通块是否选了点的贡献,转移有:

    初值:\(dp_{x,0}=1,dp_{x,1}=\dfrac ny{1-y}\)

    转移:

    1. \(dp_{x,1}\):两种情况,一种是和下边的儿子成为一个联通块,另一个是断开儿子的边(儿子的联通块必须选了标记点)。那么就是 \(dp_{x,1}\times dp_{v,0}+dp_{x,0}\times dp_{v,1}+dp_{x,1}\times dp_{v,1}\)

    2. \(dp_{x,0}\):也是要么断开要么不断。断开必须儿子选了,不断必须儿子没选。那么就是 \(dp_{x,0}\times dp_{v,0}+dp_{x,0}\times dp_{v,1}\)

    复杂度 \(O(n)\)

\(T3\) P229. 嘉然今天吃什么 \(0pts\)

  • 原题: luogu P8511 [Ynoi Easy Round 2021] TEST_68

  • 部分分

    • \(10 \%\)
      • 枚举 \(a_{i} \bigoplus a_{j}\) 可能会对哪些点产生影响,时间复杂度为 \(O(n^{3})\)

      • \(\{ a \}\) 插到 \(01Trie\) 上,每次遍历到一个新的节点就重构 \(01Trie\) ,时间复杂度为 \(O(n^{2} \log V)\)

        点击查看代码
        struct Trie
        {ll trie[3000010][2],tot=0;void init(){tot=0;memset(trie,0,sizeof(trie));}void insert(ll s){ll x=0,i;for(i=60;i>=0;i--){if(trie[x][(s>>i)&1]==0){tot++;trie[x][(s>>i)&1]=tot;}x=trie[x][(s>>i)&1];}}ll query(ll s){ll x=0,ans=0,i;for(i=60;i>=0;i--){if(trie[x][((s>>i)&1)^1]==0){x=trie[x][(s>>i)&1];}else{x=trie[x][((s>>i)&1)^1];ans|=(1ll<<i);}}return ans;}
        }T;
        struct node
        {ll nxt,to;
        }e[1000010];
        ll head[1000010],a[1000010],pos[1000010],dfn[1000010],out[1000010],ans[1000010],fa[1000010],tot=0,cnt=0;
        void add(ll u,ll v)
        {cnt++;e[cnt].nxt=head[u];e[cnt].to=v;head[u]=cnt;
        }
        void dfs1(ll x,ll fa)
        {tot++;dfn[x]=tot;pos[tot]=x;for(ll i=head[x];i!=0;i=e[i].nxt){if(e[i].to!=fa){dfs1(e[i].to,x);}}out[x]=tot;
        }
        ll ask(ll x,ll n)
        {T.init();for(ll i=1;i<=dfn[x]-1;i++){T.insert(a[pos[i]]);}for(ll i=out[x]+1;i<=n;i++){T.insert(a[pos[i]]);}ll ans=0;for(ll i=1;i<=dfn[x]-1;i++){ans=max(ans,T.query(a[pos[i]]));}for(ll i=out[x]+1;i<=n;i++){ans=max(ans,T.query(a[pos[i]]));}return ans;
        }
        int main()
        {ll n,i;cin>>n;for(i=2;i<=n;i++){cin>>fa[i];add(fa[i],i);add(i,fa[i]);}for(i=1;i<=n;i++){cin>>a[i];}dfs1(1,0);for(i=1;i<=n;i++){cout<<ask(i,n)<<endl;}return 0;
        }
        
    • \(20 \%\) :将 \(\{ a \}\) 插到 \(01Trie\) 上,可持久化 \(01Trie\) 维护,常数小的话应该可以通过。
    • 另外 \(20 \%\) :找到链顶后顺序插入,时间复杂度为 \(O(n \log n \log V)\)
  • 正解

    • 求出全局最大异或点对 \((x,y)\) ,只有 \(1 \to x,1 \to y\) 的两条链上的节点的答案不是 \(a_{x} \bigoplus a_{y}\)
    • 单独处理 \(1 \to x,1 \to y\) 的两条链上的节点即可,和链的部分分一样。
    点击查看代码
    struct Trie
    {int trie[30000010][2],end[30000010],tot=0;void init(){for(ll i=0;i<=tot;i++){trie[i][0]=trie[i][1]=end[i]=0;}tot=0;}void insert(ll s,ll id){ll x=0,i;for(i=60;i>=0;i--){if(trie[x][(s>>i)&1]==0){tot++;trie[x][(s>>i)&1]=tot;}x=trie[x][(s>>i)&1];}end[x]=id;}pair<ll,ll> query(ll s){ll x=0,ans=0,i;for(i=60;i>=0;i--){if(trie[x][((s>>i)&1)^1]==0){x=trie[x][(s>>i)&1];}else{x=trie[x][((s>>i)&1)^1];ans|=(1ll<<i);}}return make_pair(ans,end[x]);}
    }T;
    struct node
    {ll nxt,to;
    }e[1000010];
    ll head[1000010],a[1000010],vis[1000010],ans[1000010],fa[1000010],tot=0,cnt=0,sum=0;
    vector<ll>s;
    void add(ll u,ll v)
    {cnt++;e[cnt].nxt=head[u];e[cnt].to=v;head[u]=cnt;
    }
    void dfs(ll x)
    {T.insert(a[x],x);sum=max(sum,T.query(a[x]).first);for(ll i=head[x];i!=0;i=e[i].nxt){dfs(e[i].to);}
    }
    void dfs_init(ll x,ll y)
    {T.insert(a[x],x);sum=max(sum,T.query(a[x]).first);for(ll i=head[x];i!=0;i=e[i].nxt){if(e[i].to!=y){dfs(e[i].to);}}
    }
    void ask(ll x)
    {	sum=0;T.init();s.clear();for(ll i=x;i!=1;i=fa[i])	{vis[i]=1;s.push_back(i);}for(ll i=s.size()-1;i>=0;i--){dfs_init(fa[s[i]],s[i]);ans[s[i]]=sum;}
    }
    int main()
    {ll n,maxx=0,i;pair<ll,ll>tmp,pos;cin>>n;for(i=2;i<=n;i++){cin>>fa[i];add(fa[i],i);}for(i=1;i<=n;i++){cin>>a[i];T.insert(a[i],i);tmp=T.query(a[i]);if(maxx<tmp.first){maxx=tmp.first;pos=make_pair(tmp.second,i);}}vis[1]=1;ask(pos.first);ask(pos.second);for(i=1;i<=n;i++){cout<<((vis[i]==1)?ans[i]:maxx)<<endl;}return 0;
    }
    

\(T4\) P230. APJifengc \(10pts\)

  • 原题: [AGC036D] Negative Cycle
  • 部分分
    • \(10pts\) :枚举哪条边删或不删,最后跑 \(SPFA\) 判断有没有负环。

      点击查看代码
      struct node
      {ll nxt,to,w,id;
      }e[300010];
      ll head[510],a[510][510],dis[510],vis[510],num[510],cnt=0,ans=0x7f7f7f7f;
      vector<ll>sh;
      void add(ll u,ll v,ll w)
      {cnt++;e[cnt].nxt=head[u];e[cnt].to=v;e[cnt].w=w;e[cnt].id=cnt;head[u]=cnt;
      }
      pair<ll,ll>divide(ll sum,ll n)
      {ll u=ceil(1.0*sum/n),v=sum-(u-1)*n;if(v==u){v++;}return make_pair(u,v);
      }
      bool spfa(ll s,ll n)
      {memset(dis,0x3f,sizeof(dis));memset(vis,0,sizeof(vis));memset(num,0,sizeof(num));queue<ll>q;q.push(s);dis[s]=0;vis[s]=1;while(q.empty()==0){ll x=q.front();vis[x]=0;q.pop();for(ll i=head[x];i!=0;i=e[i].nxt){ll flag=0;for(ll j=0;j<sh.size();j++){if(e[i].id==sh[j]){flag=1;break;}}if(flag==0){if(dis[e[i].to]>dis[x]+e[i].w){dis[e[i].to]=dis[x]+e[i].w;num[e[i].to]=num[x]+1;if(num[e[i].to]>=n+1){return false;}if(vis[e[i].to]==0){q.push(e[i].to);vis[e[i].to]=1;}}}}}return true;
      }
      bool check(ll sum,ll n)
      {	sh.clear();for(ll i=1;i<=n*n;i++){if((sum>>i)&1){sh.push_back(i);}}return spfa(0,n+1);
      }
      void dfs(ll pos,ll sum,ll n)
      {if(pos==n*n+1){if(check(sum,n)==1){ll num=0;pair<ll,ll>tmp;for(ll i=0;i<sh.size();i++){tmp=divide(sh[i],n);num+=a[tmp.first][tmp.second];}ans=min(ans,num);}}else{dfs(pos+1,sum|(1<<pos),n);dfs(pos+1,sum,n);}
      }
      int main()
      {ll n,i,j;cin>>n;for(i=1;i<=n;i++){for(j=1;j<=i-1;j++){cin>>a[i][j];add(i,j,1);}add(i,i+1,0);for(j=i+1;j<=n;j++){cin>>a[i][j];add(i,j,-1);}}for(i=1;i<=n;i++){add(0,i,0);}dfs(1,0,n);cout<<ans<<endl;return 0;
      }
      
  • 正解
    • 逆天题面,讲题时讲都没讲,虽然讲了也听不懂。

    拜神。

    负环想到差分约束。设第 \(i\) 个点对应 \(x_i\)

    \(q_i=x_i-x_{i+1}\),首先根据初始的边可以知道 \(q_i\ge 0\)

    对于边权为 \(-1\) 的边 \(i\rightarrow j\),有 \(x_i-x_j\ge 1\),也就是 \(q_i+q_{i+1}+\dots+q_{j-1}\ge 1\)

    边权为 \(1\) 同理,有 \(x_j-x_i\le 1\),也就是 \(q_j+q_{j+1}+\dots+q_{i-1}\le 1\)

    假如我们知道 \(q_i\),那么边权为 \(-1\) 的边在区间和 \(\ge 1\) 时留下,边权为 \(1\) 的边在区间和 \(\le 1\) 时留下。也就是如果一段 \(q_i=0\),那么这段的边权为 \(-1\) 的边就要删掉,如果区间和 \(\ge 2\) 那么边权为 \(1\) 的边就要删掉。

    如果 \(q_i\ge 2\),那么显然不如 \(1\) 好。于是 \(q_i=0/1\)

    \(dp_{i,j}\) 为扫到 \(i\),最后一个 \(1\)\(q_i\),倒数第二个是 \(q_j\) 的最小代价,转移可以从 \(dp_{j,k}\) 转移,系数可以二维前缀和。复杂度 \(O(n^3)\)

总结

  • \(T2\) 忘了生成树的个数。
  • \(T3\)\(01Trie\) 树清空时没清空彻底且不会算空间,挂了 \(10pts\)

后记

  • 题目背景夹带私活。

  • 成分复杂。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/781342.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

选股指标:涨停缩倍阴战法公式

选股指标:涨停缩倍阴战法 作者: 深海游鱼 QQ:396068801 日期:2024年8月 技术交流请加QQ 396068801

指令的执行过程

指令周期 CPU从主存中每取出并执行一条指令所需的全部时间称为指令周期,不同指令的指令周期可能不同。指令周期常常用若干机器周期来表示,机器周期又叫CPU周期。每个指令周期内的机器周期数可以不等指令周期的数据流指令执行方案

乌克兰生存小技巧——坦克炮测距法

乌克兰生活小技巧 第一集 坦克炮测距法 PS:本系列教程假设您的技术在二战的水平。对于一些条件不错的同学来说,可以直接用激光测距解决问题。 众所周知,炮弹发射出去后会有一定程度的下坠,导致可能打不中目标,这时候测距显得极为重要。所以本教程将会带大家如何正确测距,…

在Kali(Debian)系统上安装dockerdocker-compose并给docker配置socks代理

APT换源、docker安装,docker-compose安装,配置docker socks代理在Kali(Debian)系统上安装docker&docker-compose并给docker配置socks代理 安装docker 方法一:使用kali官方的安装方式(经测试,安装的docker版本为20.0) 参考链接如下 Installing Docker on Kali Linux 由于…

bugbountyhunter scope BARKER:第八滴血 存储型 Storage Cross-Site Scripting XSS SVG文件上传 报告

登录后来到home页面,留言中存在一个Attach image检查 xss payload:https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS Injection#xss-in-files使用SVG进行图片上传,发现SVG文件上传成功并返回图片地址poc:https://cfceb12f2bfd-sec875.a.barker-social.…

USB Type-C的工作原理与技术分析

USB TYPE-C更加深入的应用,是从USB3.1开始的,这是因为从USB3.1开始,USB的功能开始变得更加丰富起来。 USB 3.1基本规格有SS字样的代表支持PD,有SS和10的USB标志代表支持USB3.1及PD2.0 历代USB输出功率及标志比较本图来源于:https://www.datapro.net/techinfo/what_is_usb_…

CPU的功能和基本结构

CPU的功能CPU的基本结构运算器控制器CPU中的寄存器 用户可见的寄存器

旧物利用 - 将机顶盒改造为一台Linux开发机!

家里的机顶盒淘汰下来,博主想要物尽其用,看看是否能将其改造为一台Ubuntu"开发机",故开始倒腾前言 机顶盒型号:移动魔百盒CM201-2(CH),芯片组: hi3798mv300(hi3798mv3dmm),其他型号类似 理论上适用于以下SOC:Hi3798Mv100 / Hi3798Cv200 / Hi3798Mv200 / Hi3…

7-3FM模型

FM算法全称为因子分解机 (FactorizationMachine)。它是广告和推荐领域非常著名的算法,在线性回归模型上考虑了特征的二阶交互。适合捕捉大规模稀疏特征(类别特征)当中的特征交互。FM算法全称为因子分解机 (FactorizationMachine)。 它是广告和推荐领域非常著名的算法,在线性回…

这是DDD建模最难的部分(其实很简单)

本文书接上回《为了落地DDD,我是这样“PUA”大家的》 ,欢迎关注我的同名公众号。 https://mp.weixin.qq.com/s/DjC0FSWY1bgJyLPIND5evA什么是最重要的事如果你认真读过前面的文章,那么一定知道我们的核心逻辑:领域驱动是一种价值观,这个价值观是:“领域(边界)”的明确是…

CSP17

请注意:题目背景与题目可能没有关系第一题,性质题,找到序列的最大值与最小值,我们发现如果只有正数的话和只有负数的话都很好处理,正数正序处理类似前缀加,负数后缀加,那如果正负都有,该怎么办呢?其实我们可以吧序列全变为正的或负的吧,但是需要比较一下最大值最小值,…

丰富有趣的颜色空间

颜色空间就像是一套套颜色语言,其将视觉上的颜色以数字的形式定义表示,使其能够准确描述某个颜色简介 颜色是视觉的表现,而自然界的颜色是多姿多彩的,如果让我们用语言描述一个自然界的颜色,有些人可能会用红橙黄绿蓝靛紫,外加一些修饰词,但它不太能够准确的描述一个颜色…