NOIP模拟测试26「嚎叫响彻在贪婪的机房·主仆见证了 Hobo 的离别·征途堆积出友情的永恒」
题目比较神仙,注意是题目神仙
贪婪暗示贪心,堆积暗示堆优化$\%\%\%\%\%\%\%$
两个乱搞$+$一个堆优化$dp$
嚎叫响彻在贪婪的机房
题解
对于一个序列来说只要他们差的$gcd$不为$1$就可以构成等差数列
例如
$2$ $4$ $16$
$2$与$4$差$2$ $4$与$16$差$12$
$gcd(2,12)!=1$故构成等差序列
那么我们维护公差,然后每次的差和当前公差比较,若$gcd==1$则等差数列从这里断开,否则将公差置成$gcd$
举个例子
$2$ $8$ $14$ $16$ $18$ $20$
$2$ $8$ $14$构成公差为$6$等差数列,之后$16$ $18$ $20$构成公差为$2$等差序列
显然我们可以让他们合并为公差为$2$等差序列
注意判重,判差为$1$,
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 1111111
ll read(){
ll x=0,f=1;char c=getchar();
while(!isdigit(c)){
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)){
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
set<ll> st;
set<ll> ::iterator it;
ll n,m,d=0,ans=0;
ll a[A];
void cl(ll x){
st.clear();
d=0;
ans++;
st.insert(a[x]);
}
ll gcd(ll x,ll y){
if(y==0) return x;
return gcd(y,x%y);
}
int main(){
n=read();
for(ll i=1;i<=n;i++){
a[i]=read();
}
cl(1);
for(ll i=2;i<=n;i++){
if((it=st.find(a[i]))!=st.end()) {
// printf("i=-%lld\n",i);
cl(i);
continue;
}
if(abs(a[i]-a[i-1])==1||a[i]==a[i-1]){
cl(i);
continue;
}
// printf("d=%lld\n",d);
if(d==0){
st.insert(a[i]);
d=abs(a[i]-a[i-1]);
}
else {
ll g=gcd(d,abs(a[i]-a[i-1]));
// printf("g=%lld d=%lld abs=%lld\n",g,d,abs(a[i]-a[i-1]));
if(g==1||g==0){
cl(i);
}
else {
st.insert(a[i]);
d=g;
}
}
}
printf("%lld\n",ans);
}
主仆见证了 Hobo 的离别
题解
建边,建立包含关系的树,例如$1,2$交集为$3$那么$1$包含$3$,$2$包含$3$
再例如$1,2$并集为$3$那么$3$包含$1$,$3$包含$2$
询问$x$,$y$所属关系就从$y$开始$dfs$若找到$x$即符合
暴力就是正解
让我们分析一下复杂度
题目中说
新元件的编号等于融合之前元件的总个数加一。当然,参与融合的 K个元件融合之后依然存在,并且每个元件至多参与一次融合。
数据范围

极限情况下肯定就是分开连边
那么$250000$个分开连边,产生$125000$,然后下一层产生$62500$再下一层.....
显然是$log$的最终是$18$层
而且我们建出来树是下图这样的从一点往下搜

所以极限复杂度$18*250000$可过
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 1111111
ll read(){
ll x=0,f=1;char c=getchar();
while(!isdigit(c)){
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)){
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
ll n,m,cnt,ok,tot=0;
ll some[A],fa[A],nxt[A],ver[A],head[A];
ll find(ll x){
if(fa[x]!=x){
fa[x]=find(fa[x]);
}
return fa[x];
}
void haha(){
for(ll i=1;i<=500000;i++){
fa[i]=i;
}
}
void merge(ll x,ll y){
x=find(x),y=find(y);
if(x!=y) fa[x]=y;
}
void add(ll x,ll y){
// printf("x=%lld y=%lld\n",x,y);
nxt[++tot]=head[x],head[x]=tot,ver[tot]=y;
}
void dfs(ll x,ll pre,ll ineed){
if(x==ineed) ok=1;
if(ok) return ;
for(ll i=head[x];i;i=nxt[i]){
ll y=ver[i];
if(y==pre) continue;
dfs(y,x,ineed);
}
}
/*ll ithave[A],beihave[A];
ll getithave(ll x){
if(ithave[x]!=x){
ithave[x]=getithave(ithave[x]);
}
return ithave[x];
}
void mergeit(ll x,ll y){
x=getithave(x);
y=getithave(y);
if(ithave[x]!=ithave[y]){
ithave[x]=y;
}
}
ll getbeihave(ll x){
if(beihave[x]!=x){
beihave[x]=getbeihave(beihave[x]);
}
return beihave[x];
}
void mergebei(ll x,ll y){
x=getbeihave(x);
y=getbeihave(y);
if(beihave[x]!=beihave[y]){
beihave[x]=y;
}
}*/
int main(){
n=read(),m=read();
cnt=n;
for(ll i=1,opt,ques,k,QwQ;i<=m;i++){
ques=read();
if(ques==0){
opt=read(),k=read();
cnt++;
if(opt==1){
for(ll j=1;j<=k;j++){
QwQ=read();
//1属于2 1--->2
add(cnt,QwQ);
if(k==1)
add(QwQ,cnt);
}
}
else {
for(ll j=1;j<=k;j++){
QwQ=read();
add(QwQ,cnt);
if(k==1)
add(cnt,QwQ);
}
}
}
else{
ok=0;
ques=read(),QwQ=read();
dfs(QwQ,0,ques);
printf("%lld\n",ok);
}
}
}
征途堆积出友情的永恒
题解
首先普通dp应该都会吧
$f[i]=min(f[j]+max(sum[i]-sum[j],b[j]))$
for(ll i=1;i<=n;i++){
for(ll j=max(i-k,0ll);j<=i-1;j++){
ll fee=max(sum[i]-sum[j],a[j]);
f[i]=min(f[j]+fee,f[i]);
}
}
一言不和上代码
怎么优化,
线段树或者堆
思考sum[i]变化很烦,线段树很难维护(然而Mr_zkt维护出来了$%%%$)我没打线段树
用堆维护我们需要寻找不变量显然$f[j]+b[j]$和$f[j]-sum[j]$是不变量
开两个小根堆,一个维护$min(f[j]+b[j])$一个维护$f[j]-sum[j]$
转移时$min(q1.top(),q2.top+sum[i])$
细节稍多
- $STL$的各种$empty$往上仍,
- 判断是否可以转移(<=k)限制
- 在$f[j]+b[j]$$<$$f[j]-sum[j]+sum[i]$时第一个堆不合法,第一个堆扔到第二个堆
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 1010101
ll f[A],a[A],sum[A],b[A];
ll n,k,minn;
struct node{
ll id,val;
friend bool operator < (const node &a,const node &b){
return a.val>b.val;
}
};
priority_queue<node> q1,q2;
//q1用来存f+b q2存 f-s
ll read(){
ll x=0,f=1;char c=getchar();
while(!isdigit(c)){
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)){
x=x*10+(c-'0');
c=getchar();
}
return f*x;
}
void work(){
memset(f,0x3f,sizeof(f));
f[0]=0;
node o;
o.id=0,o.val=b[0];
q1.push(o);
for(ll i=1;i<=n;i++){
node x1,x2;
while(!q1.empty()){
x1=q1.top();
if(x1.id>=i-k) break;
q1.pop();
}
while(!q2.empty()){
x2=q2.top();
if(x2.id>=i-k) break;
q2.pop();
}
while(!q1.empty()){
x1=q1.top();
if(x1.val>=f[x1.id]-sum[x1.id]+sum[i]) break;
// printf("feifa\n");
// printf("x1.val=%lld id=%lld f-s=%lld\n",x1.val,x1.id,f[x1.id]-sum[x1.id]+sum[i]);
q1.pop();
node x3;
x3.id=x1.id,x3.val=f[x1.id]-sum[x1.id];
q2.push(x3);
}
while(!q1.empty()){
x1=q1.top();
if(x1.id>=i-k) break;
q1.pop();
}
while(!q2.empty()){
x2=q2.top();
if(x2.id>=i-k) break;
q2.pop();
}
// printf("q1.top id=%lld val=%lld 2=%lld %lld\n",x1.id,x1.val,x2.id,x2.val);
//f[i]=min(x1.val,x2.val+sum[i]);
if(!q1.empty())f[i]=min(0x7ffffffffff,q1.top().val);
if(!q2.empty())f[i]=min(0x7ffffffffff,q2.top().val+sum[i]);
// printf("f[%lld]=%lld\n",i,f[i]);
x1.id=i,x1.val=f[i]+b[i];
q1.push(x1);
}
}
int main(){
n=read(),k=read();
for(ll i=1;i<=n;i++){
sum[i]=read();
sum[i]+=sum[i-1];
}
for(ll i=0;i<n;i++){
b[i]=read();
}
work();
printf("%lld\n",f[n]);
}
NOIP模拟测试26「嚎叫响彻在贪婪的机房·主仆见证了 Hobo 的离别·征途堆积出友情的永恒」的更多相关文章
- 8.19 NOIP模拟测试26(B) 嚎叫响彻在贪婪的厂房+主仆见证了 Hobo 的离别+征途堆积出友情的永恒
T1 嚎叫响彻在贪婪的厂房 以前做过一个等比数列的题「序列」,这个类似 是等差数列且公差不为1的条件就是各项差的绝对值的$gcd!=1$,每次拿出序列前两个数,求出差值,插入到set里,每次向后扩展, ...
- 征途堆积出友情的永恒「堆优化dp」
直接写题解: 很简单的dp暴力转移式子:f[i]=MAX{f[j]+max(tax[j],sum[i]-sum[j])} 观察式子,只有一个变量sum[i]; 而其他都为定量; 则考虑维护 两个定量: ...
- NOIP模拟测试19「count·dinner·chess」
反思: 我考得最炸的一次 怎么说呢?简单的两个题0分,稍难(我还不敢说难,肯定又有人喷我)42分 前10分钟看T1,不会,觉得不可做,完全不可做,把它跳了 最后10分钟看T1,发现一个有点用的性质,仍 ...
- NOIP模拟测试30「return·one·magic」
magic 题解 首先原式指数肯定会爆$long$ $long$ 首先根据欧拉定理我们可以将原式换成$N^{\sum\limits_{i=1}^{i<=N} [gcd(i,N)==1] C_{G ...
- NOIP模拟测试21「折纸·不等式」
折纸 题解 考试时无限接近正解,然而最终也只是接近而已了 考虑模拟会爆炸,拿手折纸条试一试,很简单 考你动手能力 代码 #include<bits/stdc++.h> using name ...
- NOIP模拟测试18「引子·可爱宝贝精灵·相互再归的鹅妈妈」
待补 引子 题解 大模拟,注意细节 代码1 #include<bits/stdc++.h> using namespace std; int n,m;char a[1005][1005]; ...
- NOIP模拟测试11「string·matrix·big」
打的big出了点小问题,maxx初值我设的0然后少了10分 第二题暴力打炸 第一题剪了一些没用的枝依然40分 总分70 这是一次失败的考试 string 想到和序列那个题很像,但我没做序列,考场回忆学 ...
- NOIP模拟测试10「大佬·辣鸡·模板」
大佬 显然假期望 我奇思妙想出了一个式子$f[i]=f[i-1]+\sum\limits_{j=1}^{j<=m} C_{k \times j}^{k}\times w[j]$ 然后一想不对得容 ...
- 20190803 NOIP模拟测试12「斐波那契(fibonacci)· 数颜色 · 分组 」
164分 rank11/64 这次考的不算太差,但是并没有多大的可能性反超(只比一小部分人高十几分而已),时间分配还是不均,T2两个半小时,T1半个小时,T3-额十几分钟吧 然额付出总是与回报成反比的 ...
随机推荐
- 北航OO(2020)第四单元博客作业暨学期总结
一.第四单元架构设计 1.第一次作业 我在本次作业中设置了多个储存结构:Directory,ElementsInName,ElementsInId,Cache. Directory: 顾名思义,这是个 ...
- GPUImage移植总结
项目github地址: aoce 我是去年年底才知道有GPUImage这个项目,以前也一直没有在移动平台开发过,但是我在win平台有编写一个类似的项目oeip(不要关注了,所有功能都移植或快移植到ao ...
- Davinci 可视化系统部署安装及简单使用
Davinci 是一个目前比较热门的国内开源BI系统,功能比较完善,各种可视化效果也挺不错.主要获取数据的方式是通过编写SQL 创建数据视图来展示各种图表的. Davinci面向业务人员/数据工程师/ ...
- VSCode·备份&还原配置及拓展项
阅文时长 | 0.54分钟 字数统计 | 924字符 主要内容 | 1.引言&背景 2.备份VSCode配置 3.还原VSCode配置 4.Syncing常用命令 5.声明与参考资料 『VSC ...
- 都 2021 年了,竟然有人搞大数据时忽略 JSON 而去研究用 C# 把 XML 转换为 XML 的技术
在大数据项目开发过程中,ETL(Extract-Transform-Load)是必不可少.即便目前 JSON 非常流行,开发人员也有必定会有对远古系统的挑战,而 XML 格式的数据源作为经典存在浑身上 ...
- Linux上使用iSCSI概述
iSCSI简介 1. scsi和iscsi SCSI技术是存储设备最基本的标准协议,通常需要设备互相靠近并用SCSI总线连接,因此受到物理环境的限制 iSCSI(Internet Small Comp ...
- Java 线程池 ThreadPoolExecutor 的使用
引言 JAVA 语言为我们提供了两种基础线程池的选择: ThreadPoolExecutor ScheduledThreadPoolExecutor 它们都实现了 ExecutorService 接口 ...
- 源码安装nginx env
源码安装nginx 1. For ubuntu:18.04 apt -y install build-essential libtool libpcre3 libpcre3-dev zlib1g-de ...
- 再见Xshell、Xftp!Python执行Linux命令、上传下载远程文件
相信大家应该都接触过Linux操作系统(Ubuntu.Centos等),那么在使用的Linux操作系统需要使用一些远程ssh工具,尤其是公网服务器. 常用的ssh工具主要有:Xshell.MobaXt ...
- Jmeter- 笔记3 - Jmeter录制功能 / 抓包
http代理服务器录制脚本: 1.新建线程组 2.添加 http代理服务器 元件 3.http代理服务器修改: 1)端口:8899,任意给个无占用的 2)目标控制器:改成刚刚新建的线程组.不改就录制会 ...