【题解】CPS-S模拟2

news/2024/12/21 23:44:21/文章来源:https://www.cnblogs.com/ywhhdjser-97/p/18402499

目录
  • Pre
  • T1.不相邻集合
    • 题目描述
    • 部分分
      • 40pts
      • 10pts
    • 正解
      • 思路
      • 代码
  • T2.线段树
    • 题目描述
    • 部分分
      • 20pts
    • 正解
      • 思路
      • 代码
  • T3.
    • 部分分
      • 40pts
    • 正解
      • 思路
      • 代码
  • T4.
    • 部分分
      • 10pts
    • 正解
      • 思路
      • 代码
  • And

Pre

image
赛时没有第一时间找到签到题,遂四处游走,后来决定先打T1,约1h时切了,然后1h打后3题暴力,后面推了推T4一个特殊性质,推了推T2一个特殊性质,但是T2的推假了。不太清楚怎么就来到了最后半小时,推T2的第二个特殊性质,未果,最后15min想到了T4的 \(O(n^2)\) 暴力但是没打完,算挂分吗。

T1.不相邻集合

题目描述

定义一个可重集合是不相邻集合当且仅当集合中任意两个数的差 \(\ge2\)。现在给你一个序列 \(a\),对于它的所有前缀求能组成的最大的不相邻集合的大小。

部分分

40pts

\(O(n^2)\) DP。设 \(dp[i][0]\) 表示以 \(i\) 值开头的最大不相邻集合的大小,\(dp[i][1]\) 表示以 \(i\) 值结尾的最大不相邻集合的大小,则有转移:

\[dp[i][0]=max\,dp[j][0](j\ge i+2) +1 \]

\[dp[i][1]=max\,dp[j][1](j\le i-2) +1 \]

注意 \(+1\) 一定要放在取max外面。

10pts

在所有 \(a_i\) 都是奇数的情况下,我们任选不重复的数它们的差都一定 \(\ge2\),去重后直接统计即可。

正解

思路

对40pts的暴力进行优化。首先,重复的元素绝对没有任何贡献,所以仿照10pts的处理,先去重,也就是如果有重复的数,直接输出旧有的答案,然后不进行任何处理。
发现复杂度瓶颈在转移,有 \(O(n)\) 的遍历取max。区间最大值使我们想到线段树,于是这个东西用两颗线段树维护,支持单点赋值、区间查找最大值,复杂度 \(O(n\log n)\)

代码

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
#define inf 0x3f3f3f3f
int a,b[300003],mx,mn,num;
bool use[500005];
struct XDS
{#define N 2200022int left[N],right[N],num[N];il int lft(int x){return x<<1;}il int iht(int x){return x<<1|1;}il void pu(int x){num[x]=max(num[lft(x)],num[iht(x)]);}void make(int x,int lt,int rt){left[x]=lt;right[x]=rt;if(lt==rt){num[x]=0;return;}ri me=(lt+rt)>>1;make(lft(x),lt,me);make(iht(x),me+1,rt);pu(x);}void add(int x,int pl,int y){if(left[x]==right[x]){num[x]=y;return;}ri me=(left[x]+right[x])>>1;if(pl<=me){add(lft(x),pl,y);}else{add(iht(x),pl,y);}pu(x);}int found(int x,int lt,int rt){if(lt>rt){return 0;}if(lt<=left[x]&&right[x]<=rt){return num[x];}ri me=(left[x]+right[x])>>1,rn=-inf;if(lt<=me){rn=max(rn,found(lft(x),lt,rt));}if(rt>me){rn=max(rn,found(iht(x),lt,rt));}return rn;}#undef N
}tree[2];
int main()
{scanf("%d",&a);mx=-inf,mn=inf;for(ri i=1;i<=a;i++){scanf("%d",&b[i]);mx=max(mx,b[i]);mn=min(mn,b[i]);}tree[0].make(1,1,mx);tree[1].make(1,1,mx);for(ri i=1;i<=a;i++){if(use[b[i]]){printf("%d ",num);continue;}use[b[i]]=true;ri j=tree[0].found(1,b[i]+2,mx);tree[0].add(1,b[i],j+1);num=max(num,j+1);j=tree[1].found(1,mn,b[i]-2);tree[1].add(1,b[i],j+1);num=max(num,j+1);printf("%d ",num);}return 0;
}

T2.线段树

题目描述

void build(int i, int l, int r) {L[i] = l; R[i] = r;if (l == r) return;int mid = (l+r)/2;build(i*2, l, mid); build(i*2+1, mid+1, r);
}

以上面的代码运行一遍build(1,1,n),求 \(\sum\limits_{i\in[x,y]}i\),答案 \(\bmod 10^9+7\)\(1\le x\le y\le n\le 10^{18}\)

部分分

20pts

暴力建树,统计区间和,复杂度 \(O(n\log n)\)

正解

思路

发现复杂度主要来源于建树,考虑省略这一步,也就是 \(O(1)\) 求解某点的权值。设 \(f()\) 表示在一定条件下以某位置为根的总贡献,首先可知这个东西只和区间长度 \(n\) 和根值 \(x\) 有关,所以设为 \(f(n,x)\)(因为 \(n\) 值定了,以其为根的树的形态就定了;此时很显然它的左右儿子的值可以用根值表示,而下面的后代又可以被其左右儿子的值表示,以此类推,只要 \(n,x\) 定了,\(f()\) 的值就定了)。
然后通过理性分析||打表找规律,发现当 \(n\) 值定了以后,\(f(n,x)\) 是关于 \(x\) 的一次函数。
image
这是初始树。
image
这是改变后的树。发现当根值 \(+a\)\(f(n,a)\)一定加的是 \(ka\),这时 \(f(n,x)\) 显然是一个一次函数,且这个 \(k\) 貌似只和树的形态有关系,也就是只和 \(n\) 有关系。\(x=0\) 时取到的\(b\)值同理,也只和 \(n\) 有关系。
\(f(n,x)=k_nx+b_n\),已知一个重要等式:

\[f(n,x)=f(\lceil{\tfrac{n}{2}}\rceil,2x)+f(\lfloor{\tfrac{n}{2}}\rfloor,2x+1)+x \]

左右两边同时展开,得:

\[k_nx+b_n=2k_{\lceil{\tfrac{n}{2}}\rceil}x+b_{\lceil{\tfrac{n}{2}}\rceil}+2k_{\lfloor{\tfrac{n}{2}}\rfloor}x+k_{\lfloor{\tfrac{n}{2}}\rfloor}+b{\lfloor{\tfrac{n}{2}}\rfloor}+x \]

合并同类项,得:

\[k_nx+b_n=(2k_{\lceil{\tfrac{n}{2}}\rceil}+2k_{\lfloor{\tfrac{n}{2}}\rfloor}+1)x+b_{\lceil{\tfrac{n}{2}}\rceil}+k_{\lfloor{\tfrac{n}{2}}\rfloor}+b{\lfloor{\tfrac{n}{2}}\rfloor} \]

由于是一次函数相同,所以 \(k,b\) 得分别相同,也就是:

\[\begin{cases}k_n=2k_{\lceil{\tfrac{n}{2}}\rceil}+2k_{\lfloor{\tfrac{n}{2}}\rfloor}+1\\b_n=b_{\lceil{\tfrac{n}{2}}\rceil}+k_{\lfloor{\tfrac{n}{2}}\rfloor}+b{\lfloor{\tfrac{n}{2}}\rfloor}\end{cases} \]

然后就可以使用记搜 \(O(\log n)\) 的复杂度内求解线段树上一个节点的贡献了。外层还是线段树的查询,只不过不建树,递归记录区间左右端点,找到合法区间直接原地统计答案,所以再带上外层线段树的 \(\log n\),总复杂度 \(O(T\log^2n)\)

代码

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
#define inf 0x3f3f3f3f
int a;
const int mod=1e9+7;
long long b,c,d;
map<long long,long long>kk,bb;
il long long K(long long x)
{if(x==1){return 1;}if(kk[x]){return kk[x];}kk[x]=((K(x>>1)<<1)+(K(((x+1)>>1))<<1)+1)%mod;return kk[x];
}
il long long B(long long x)
{if(x==1){return 0;}if(bb[x]){return bb[x];}bb[x]=(B(x>>1)+B((x+1)>>1)+K(x>>1))%mod;return bb[x];
}
il long long got(long long x,long long y)
{return (K(x)*y+B(x))%mod;
}
long long found(long long x,long long lt,long long rt,long long left,long long right)
{if(lt<=left&&right<=rt){return got(right-left+1,x);}register long long me=(left+right)>>1,rn=0;if(lt<=me){rn+=found((x<<1)%mod,lt,rt,left,me);rn%=mod;}if(rt>me){rn+=found((x<<1|1)%mod,lt,rt,me+1,right);rn%=mod;}return rn;
}
int main()
{scanf("%d",&a);while(a--){scanf("%lld%lld%lld",&b,&c,&d);printf("%lld\n",found(1,c,d,1,b));}return 0;
}

T3.

部分分

40pts

正解

思路

代码

T4.

部分分

10pts

正解

思路

代码

And

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

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

相关文章

SpringBoot集成knife4j接口文档

0. 导入maven依赖 <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId> </dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lom…

Cisco Catalyst 9000 Series Switches, IOS XE Release 17.15.1 ED

Cisco Catalyst 9000 Series Switches, IOS XE Release 17.15.1 EDCisco Catalyst 9000 Series Switches, IOS XE Release 17.15.1 ED 思科 Catalyst 9000 交换产品系列 IOS XE 系统软件 请访问原文链接:https://sysin.org/blog/cisco-catalyst-9000/,查看最新版。原创作品,…

dbeaver导出表结构和数据,无需二次操作

1. 对某个数据库右键(示例demo)→工具→转储数据库 2.接着按下面进行操作:3.创建跟上面同名字的数据库: 右键数据库名字-》工具-》执行脚本 导入数据,执行sql文件时报错unknown command \\. 在额外的命令参数中添加下面命令即可: --default-character-set=utf8

Day01 MarkDown语法学习

MarkDown语法学习 标题 #+空格 一级标题 ##+空格 二级标题字体 粗体 **粗体** 斜体 *斜体* 斜体加粗 ***斜体加粗*** 删除线 ~~删除~~ 引用引用 > 引用分割线---或者***图片![截图2](https://cdn.luogu.com.cn/upload/usericon/1.png) 超链接 我的博客 [我的博客](https://w…

Graph Edge Partitioning via Neighborhood Heuristic

目录概符号说明Vertex vs Edge partitioningNE (Neighbor Expansion)代码Zhang C., Wei F., Liu Q., Tang Z. G. and Li Z. Graph edge partitioning via neighborhood heuristic. KDD, 2017.概 本文提出了一种图分割方法 (edge partitioning), 保证只有少量的重复结点. 符号说…

P11020 「LAOI-6」Radiation 题解

一道简单的构造题,其实不用想的十分复杂的说。 首先,最多发射的宇宙射线 \(sum\) 也最多为 \(sum_{max}=min(m,n)\) 也就是说,无论如何摆放石子,也只能达到这个数量。那么我们的目的便变成了如何让石子变成这一个形状。如上图,在一个 \(3\times6\) 的矩阵中,其实只要三颗…

适合科研的团队协作工具:8款实用评测

本文介绍的8款工具如下:1.Worktile;2.PingCode;3.蓝湖;4.智方科研管理系统;5.九云办公;6.和鲸ModelWhale;7.有道云协作;8.Maxhub。在科研项目中,团队协作软件的选择总是让人头疼。市面上有太多工具,不知道哪款更适合自己?每个软件都宣传自己效率高、功能全,但真正好…

精选10款团队协作工具,让合作更高效

本文将介绍10款团队协作工具:1.Worktile;2.PingCode;3.哨子办公;4.智办事;5.曲奇云盘;6.小钉贴;7.协同易;8.BoardMix;9.CORNERSTONE;10.ORGOS。团队合作中总是有很多信息来回传递,却没有一个统一的平台来管理任务和沟通,这不仅让工作效率大打折扣,还可能让团队成员…

1-2Java基本数据类型

Java基本数据类型 变量就是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间。 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。因此,通过定义不同类型的变量,可以在内存中储存整数、小数或者字符。 Java 的两大数据…

知识库软件对比:10款适合团队的工具揭秘

本文将介绍10款知识库软件:1.PingCode; 2. Worktile; 3. 亿方云; 4. 掘金文档; 5. 问道文档; 6. 海豚智库; 7. 麦客; 8. Helpjuice; 9. Confluence; 10. FlowUs。如今,团队协作越来越依赖于高效的工具,而一个简单、易用的知识库软件能极大提升工作效率。面对市场上…

南方科技大学院士分析

网页信息获取分析报告 1.Python获取页面信息 这里需要爬取的是南方科技大学研究生院-师资概况页面,使用的是requests和BeautifulSoup方法 以下是要爬取的页面import requests from bs4 import BeautifulSoup import pandas as pd import matplotlib.pyplot as plt import seab…

VNC简明教程

VNC的安装方法 VNC是一款局域网远程工具。 安装包: https://cry33.lanzoum.com/b00oc0kmj密码:3zum 激活码: FBV9V-7Z3V9-MED3U-47SEU-85T3A 安装过程很简单,一直点下一步就行。激活有两种方式,第一种是邮箱激活,第二种是激活码激活。我们选择第二种激活方式,直接将上面的…