题面:https://www.cnblogs.com/Juve/articles/11376806.html

A. 嚎叫响彻在贪婪的厂房:

是时候学习一下map和set的用法了。。。。。。

贪心:区间[L,R]合法的条件:所有相邻两数差的绝对值的gcd不等于1,且没有重复的元素

gcd比较好满足,判重用map或set都可以

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#define MAXN 100005
#define int long long
using namespace std;
int n,a[MAXN],d,ans=0;
set<int>s;
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
s.insert(a[1]);
for(int i=1;i<=n;i++){
d=gcd(d,abs(a[i]-a[i-1]));
if(d==1||s.find(a[i])!=s.end()){
ans++;
d=0;
s.clear();
}
s.insert(a[i]);
}
printf("%lld\n",ans);
return 0;
}

B. 主仆见证了 Hobo 的离别

题解说什么离线建树。。。

其实只用xgdfs在线搜索

如果是交,我们就建立由新点指向原点的有向边,表示新点有的元素原点也有

并就反过来,当然我们要特判k=1的情况,因为此时交和并等价,建双向边即可,

查询的话dfs,只要x能到y就行

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define MAXN 500005
using namespace std;
int n,m;
int to[MAXN<<1],nxt[MAXN<<1],pre[MAXN],cnt=0;
void add(int u,int v){
cnt++,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt;
}
bool dfs(int x,int fa,int opt){
if(x==opt) return 1;
for(int i=pre[x];i;i=nxt[i]){
int y=to[i];
if(y==fa) continue;
if(dfs(y,x,opt)) return 1;
}
return 0;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1,opt;i<=m;i++){
scanf("%d",&opt);
if(opt==0){
n++;
int op,k;
scanf("%d%d",&op,&k);
for(int j=1,x;j<=k;j++){
scanf("%d",&x);
if(k==1) add(x,n),add(n,x);
else if(op==0) add(n,x);
else if(op==1) add(x,n);
}
}else{
int x,y;
scanf("%d%d",&x,&y);
if(dfs(x,0,y)) puts("1");
else puts("0");
}
}
return 0;
}

C. 征途堆积出友情的永恒

有一个明显的50分dp:

设sum[i]表示前缀和,那么f[i]=min(f[j]+max(sum[i]-sum[j],b[j+1]))

n2转移,再加上三个特判,可以得到80分:

#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 500005
#define int long long
#define inf 0x7ffffffffffffff
#define re register
using namespace std;
int n,k,a[MAXN],sum[MAXN],b[MAXN],f[MAXN];
bool flag1=0,flag2=0;
int max(int a,int b){
return a>b?a:b;
}
int min(int a,int b){
return a<b?a:b;
}
signed main(){
scanf("%lld%lld",&n,&k);
for(re int i=1;i<=n;i++){
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
}
for(re int i=0;i<n;i++){
scanf("%lld",&b[i]);
if(b[i]!=1) flag1=1;
if(b[i]!=a[i+1]) flag2=1;
f[i+1]=inf;
}
if(flag1==0||flag2==0){
printf("%lld\n",sum[n]);
return 0;
}
if(k==n){
printf("%lld\n",max(b[0],sum[n]));
return 0;
}
for(re int i=1;i<=n;i++){
for(re int j=max(0,i-k);j<=i-1;j++)
f[i]=min(f[i],f[j]+max(sum[i]-sum[j],b[j]));
}
printf("%lld\n",f[n]);
return 0;
}

可以用堆优化dp:

建两个小根堆,一个维护 f[j]+b[j+1] ,另一个维护 f[j]-sum[j] ,则答案为 min(第一个堆的最小值,第二个堆的最小值+sum[i]) 。
如果取到的j小于i-k,则弹出堆顶继续取。
在第一个堆中取数时,如果发现它比 f[j]-sum[j]+sum[i]小,则把j加进第二个堆,弹出第一个堆的堆顶继续取,直到取到符合条件的为止。
显然,一个j至多进堆2次,出堆2次。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define MAXN 500005
#define int long long
#define inf 0x7ffffffffffffff
#define re register
using namespace std;
int n,k,a[MAXN],sum[MAXN],b[MAXN],f[MAXN];
int max(int a,int b){
return a>b?a:b;
}
int min(int a,int b){
return a<b?a:b;
}
struct node{
int val,pos;
friend bool operator < (node a,node b){
return a.val==b.val?a.pos>b.pos:a.val>b.val;
}
};
priority_queue<node>q1,q2;
signed main(){
scanf("%lld%lld",&n,&k);
for(re int i=1;i<=n;i++){
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
}
for(re int i=0;i<n;i++){
scanf("%lld",&b[i]);
f[i+1]=inf;
}
q1.push((node){f[0]+b[0],0});
for(re int i=1;i<=n;i++){
while(!q1.empty()&&(q1.top().pos<i-k)) q1.pop();
while(!q2.empty()&&(q2.top().pos<i-k)) q2.pop();
while(!q1.empty()){
int j=q1.top().pos;
if(q1.top().val>=f[j]-sum[j]+sum[i]) break;
q1.pop();
if(j<i-k) continue;
q2.push((node){f[j]-sum[j],j});
}
while(!q1.empty()&&(q1.top().pos<i-k)) q1.pop();
while(!q2.empty()&&(q2.top().pos<i-k)) q2.pop();
if(!q1.empty()) f[i]=min(f[i],q1.top().val);
if(!q2.empty()) f[i]=min(f[i],q2.top().val+sum[i]);
q1.push((node){f[i]+b[i],i});
}
printf("%lld\n",f[n]);
return 0;
}

HZOI20190819模拟26题解的更多相关文章

  1. HZOJ 20190819 NOIP模拟26题解

    考试过程: 照例开题,然后觉得三道题都挺难,比昨天难多了(flag×1),T1 dp?T2 数据结构? T3 dp?事实证明我是sb然后决定先搞T2,但是,woc,这题在说什么啊,我怎么看不懂题啊,连 ...

  2. [NOIP模拟26]题解

    今天的考试题改自闭了……所以滚来写陈年题解. A.*****贪婪***** RT,出题人告诉我们这题要贪心. 最优的策略一定是拖到必须断的时候再断开(虽然并不知道为什么). 如果一段序列满足题目中的性 ...

  3. [CQOI2012]模拟工厂 题解(搜索+贪心)

    [CQOI2012]模拟工厂 题解(搜索+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327574 链接题目地址:洛谷P3161 BZOJ P26 ...

  4. noip模拟26[肾炎黄·酱累黄·换莫黄]

    \(noip模拟26\;solutions\) 这个题我做的确实是得心应手,为啥呢,因为前两次考试太难了 T1非常的简单,只不过我忘记了一个定理, T2就是一个小小的线段树,虽然吧我曾经说过我再也不写 ...

  5. NOIP第7场模拟赛题解

    NOIP模拟赛第7场题解: 题解见:http://www.cqoi.net:2012/JudgeOnline/problemset.php?page=13 题号为2221-2224. 1.car 边界 ...

  6. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  7. HGOI NOIP模拟4 题解

    NOIP国庆模拟赛Day5 题解 T1 马里奥 题目描述 马里奥将要参加 NOIP 了,他现在在一片大陆上,这个大陆上有着许多浮空岛,并且其中一座浮空岛上有一个传送门,马里奥想要到达传送门从而前往 N ...

  8. 10.8 wtx模拟题题解

    填坑 orz w_x_c_q w_x_c_q的模拟赛(150pts,炸了) money 题目背景: 王小呆又陷入自己的梦里.(活在梦里...) 题目描述: 王小呆是一个有梦想的小菜鸡,那就是赚好多好多 ...

  9. [NOIP模拟13]题解

    A.矩阵游戏 其实挺水的? 考场上根本没有管出题人的疯狂暗示(诶这出题人有毛病吧这么简单的东西写一大堆柿子),而且推公式能力近乎没有,所以死掉了. 很显然乘法有交换率结合率所以操作顺序对最终结果没什么 ...

随机推荐

  1. 【JZOJ6367】工厂(factory)

    description 大神 wyp 开了家工厂,工厂有 n 个工人和 p 条流水线. 工厂的工人都是睡神,因此第 i 个工人只会在 si 至 ti 时刻才会工作. 每个工人都会被分派到一条流水线上, ...

  2. 【JZOJ6345】ZYB建围墙

    description analysis 打表找规律,自认为样例给的提示很明显 容易想到最优方案是让家庭尽量先围成一个正六边形,剩下的在最外层绕一个圈 手推一波可以知道,如果正六边形有\(n\)层,剩 ...

  3. Vue+Iview+Node 搭建数据模拟接口

    1.初始化node 项目 2.安装需要部件 3.编写简单代码 routers=>:index.js  login.js  users.js 根目录 index.js var express=re ...

  4. LUOGU P4394 [BOI2008]Elect 选举 (背包)

    传送门 解题思路 一眼看上去就像个背包,然后就是\(0/1\)背包改一改,结果发现过不了样例.后来想了一下发现要按\(a\)从大到小排序,因为如果对于一个>=总和的一半但不满足的情况来说,把最小 ...

  5. 缓冲(cache)和缓存(buffer)

    缓存: 指把常用数据存储到可以快速获取的区域,以备重复利用 一般叫做cache. 缓存能提高效率 缓冲: 是指在数据流转过程中,不同层次速度不一致时,利用缓冲区来缓解上下层之间速率问题(性能差异) 一 ...

  6. JS while 循环

    while循环:只要条件成立,就重复不断的执行循环体代码 while(条件判断) { 如果条件为true,则执行循环体代码 } while循环结构说明:   在循环开始前,必须要对变量初始化(声明变量 ...

  7. 数据可视化(matplotilb)

    一,matplotilb库(数学绘图库) mat数学 plot绘图  lib库 matplotlib.pyplot(缩写mp)->python 最常用接口 mp.plot(水平坐标,垂直坐标数组 ...

  8. C# 串口编程 对端口的访问被拒绝

    感谢Sunny秋刀鱼.https://www.cnblogs.com/527289276qq/p/5595798.html 在页面或者窗口Unloaded事件中关闭串口即可.

  9. selenium学习笔记11——driver.get(url) 页面加载时间太长

    在执行自动化测试用例过程中,发现因为网络慢或其他原因导致driver.get(url) 时,页面一直在加载,页面没有加载完成就不会去继续执行下面的动作,但是实际上需要操作的元素已经加载出来了. 解决方 ...

  10. AutoIt自动化编程(4)【转】

    五.自动化操作轻松入门系列5 控件操作 然而,在真正实现自动化时仅靠上面的技术往往难以达到预期目的.下面开始进入最为重要的控件操作. 1.设置文本 在安装软件的过程中用户往往需要提供一些必需信息,比如 ...