EZ 2018 06 02 NOIP2018 模拟赛(十七)
这次的比赛是真心比较狗,我TM的写了30min的树剖ZZ地直接memset超时了
话说我既然想到差分就应该去写差分的啊!
好了不过这次Rank还挺高的,终于要打进前10了当然是假的了。
好了下面开始讲题。链接
A. 幻灯结界
一道非常基础的贪心题,我们只需要两次贪心即可解决。
首先是对于改变防御值的问题,我们可以用一个很显然并且正确的贪心:总是把机会给最小的并且这个最小值应该小于改变的值。否则就没有得到最大的利用。
然后对于下一步我们可以通过一个叫排序不等式的东西。说白了就是:大的对大的,小的对小的。这样就可以保证\(max(b_i-a_i)\)最小。
其实上面的东西只需要用正常人的思想感性理解一下即可。
然后我们就sort一下,然后扫一遍即可。
CODE
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=200005;
int a[N],b[N],n,x,y,ans;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
//freopen("A.in","r",stdin); freopen("A.out","w",stdout);
register int i; read(n); read(x); read(y);
for (i=1;i<=n;++i)
read(a[i]); sort(a+1,a+n+1);
for (i=1;i<=n;++i)
read(b[i]); sort(b+1,b+n+1);
for (i=1;i<=n&&x>0;++i)
{
if (a[i]>=y) break;
a[i]=y; --x;
}
sort(a+1,a+n+1);
for (i=1;i<=n;++i)
ans=max(ans,b[i]-a[i]);
printf("%d",ans);
return 0;
}
B. 时之终末
一道很不错的状压DP的题。
首先我们发现数据范围:\(a<=16\),所以果断状压。
设\(f_{i,j}\)表示前\(i\)个数中末尾\(j\)个数的情况(\(j\)不足则在前面补0),其中\(j\)是一个二进制数
其每一位分别表示对应位置上的数是否被选,例如当\(j=6\)时:
代表的状态为\(110\),即表示这个数位置\(x\)之前的\(a_{x-2}\)和\(a_{x-1}\)都被选择了(不足则补0)
所以我们就能比较轻易地写出转移方程:
- \(f_{i,k}=max(f_{i,k},f_{i-1,j}+i>=a?s_k:0)\)(表示不选\(i\)这个位置上的数)
- \(f_{i,k|1}=max(f_{i,k|1},f_{i-1,j}+a_i+i>=a?s_k:0)\)(表示选\(i\)这个位置上的数)
其中,\(k=j<<1\)。其实就是把之前的状态都往前1位然后把新的添加进来。
\(s_k\)表示当状态是\(k\)时,通过额外方式获得的奖励分数。
那么接下来就是如何枚举这个\(s_k\)的问题了。
我们可以先分别处理出所有状态的情况,然后通过经典的枚举子集方法来解决。
我们设\(t_i\)表示一种状态为\(i\)的奖励价值,则有:
for (i=0;i<=cnt;++i)
for (j=i;j!=0;j=(j-1)&i)
s[i]+=t[j];
以上预处理的复杂度为\(O(3^a)\)。然后我们滚存一下\(f_{i,j}\)即可
CODE
#include<cstdio>
#include<cstring>
using namespace std;
const int N=105,M=55,STATE=(1<<16)+5;
int f[2][M][STATE],v[N],c[STATE],t[STATE],n,m,a,b,x,y,z,cnt,s,ans;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc(); int flag=1;
while (ch<'0'||ch>'9') { if (ch=='-') flag=-1; ch=tc(); }
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc(); x*=flag;
}
inline int min(int a,int b)
{
return a<b?a:b;
}
inline int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
//freopen("B.in","r",stdin); freopen("B.out","w",stdout);
register int i,j,k;
read(n); read(m); read(a); read(b);
for (i=1;i<=n;++i)
read(v[i]);
for (i=1;i<=b;++i)
{
read(x); read(y); s=0;
for (j=1;j<=x;++j)
read(z),s|=1<<(a-z);
t[s]+=y;
}
cnt=(1<<a)-1;
for (i=0;i<=cnt;++i)
for (j=i;j!=0;j=(j-1)&i)
c[i]+=t[j];
memset(f[0],163,sizeof(f[0])); int INF=f[0][0][0]; f[0][0][0]=0;
for (i=1;i<=n;++i)
{
int now=i&1,lst=now^1; memset(f[now],163,sizeof(f[now]));
for (j=0;j<=min(i-1,m);++j)
for (k=0;k<=cnt;++k)
if (f[lst][j][k]!=INF)
{
s=(k<<1)&cnt;
f[now][j][s]=max(f[now][j][s],f[lst][j][k]+(i>=a?c[s]:0));
f[now][j+1][s|1]=max(f[now][j+1][s|1],f[lst][j][k]+v[i]+(i>=a?c[s|1]:0));
}
}
for (ans=INF,i=0;i<=m;++i)
for (j=0;j<=cnt;++j)
ans=max(ans,f[n&1][i][j]);
printf("%d",ans);
return 0;
}
C. 伪神
一道需要思考的题目,告诉我们有些东西是暴力树剖也剖不过去的。
首先这题目一眼就可以看出上树剖的可能性,然后我们根据题意直接主席树修改最后查询大于t的数有即可
其实这个是一个树上差分的板子题。
我们先来讲一下差分这个东西(注意这不是差分约束)。我们现在开始考虑一个问题,我们对线性上的一段区间实行全部+1的操作,然后这个数组的值的变化。
我们可以发现,操作的区间\(x,y\)之间的数它们之间的相对值是不变的。
然后我们再结合前缀和的思想,令一个前缀和数组\(sum_i\)。然后我们每次操作的时候只需要把\(sum_x+1\)然后\(sum_{y+1-1}\)即可
最后我们只需要累加这个\(sum\)数组的值即可
然后对于树上的操作其实也是一样的,我们只需要在树剖过后的序列上差分即可
但是注意最后这个统计的过程是\(O(n)\)的,那么复杂度就让人受不了了。
我们再次利用差分的重要性质:操作区间内的数之间的相对着不变,我们每一次也只需要把操作过的区间单独做一下即可。中间那些没有用的直接弹掉即可。
然后就可以用一种类似于离散化并去重的方法最后sort一下累加区间即可
不过这样由于sort的复杂度只能得96pts,AC需要更高级的离线基排,这里只写了sort的96分版
具体操作还是看CODE吧
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=100005;
struct edge
{
int to,next;
}e[N<<1];
int n,m,a,b,x,y,t,cnt,tot,ans,rt=1,num,sum[N],head[N],dep[N],son[N],size[N],father[N],top[N],id[N],q[N*5];
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc(); int flag=1;
while (ch<'0'||ch>'9') { if (ch=='-') flag=-1; ch=tc(); }
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc(); x*=flag;
}
inline void write(int x)
{
if (x/10) write(x/10);
putchar(x%10+'0');
}
inline void add(int x,int y)
{
e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt;
}
inline void swap(int &a,int &b)
{
int t=a; a=b; b=t;
}
inline void modify(int x,int y)
{
q[++num]=x; q[++num]=y+1; ++sum[x]; --sum[y+1];
}
inline void DFS1(int now,int fa,int d)
{
father[now]=fa; dep[now]=d; size[now]=1; int res=-1;
for (register int i=head[now];i!=-1;i=e[i].next)
if (e[i].to!=fa)
{
DFS1(e[i].to,now,d+1);
size[now]+=size[e[i].to];
if (size[e[i].to]>res) res=size[e[i].to],son[now]=e[i].to;
}
}
inline void DFS2(int now,int topf)
{
id[now]=++tot; top[now]=topf;
if (!son[now]) return;
DFS2(son[now],topf);
for (register int i=head[now];i!=-1;i=e[i].next)
if (e[i].to!=father[now]&&e[i].to!=son[now]) DFS2(e[i].to,e[i].to);
}
inline void change(int x,int y)
{
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
modify(id[top[x]],id[x]); x=father[top[x]];
}
if (dep[x]<dep[y]) swap(x,y);
modify(id[y],id[x]);
}
inline void updata(int x)
{
modify(id[x],id[x]+size[x]-1);
}
int main()
{
//freopen("C.in","r",stdin); freopen("C.out","w",stdout);
register int i; read(n); read(m);
memset(e,-1,sizeof(e));
memset(head,-1,sizeof(head));
for (i=1;i<n;++i)
read(x),read(y),add(x,y),add(y,x);
DFS1(rt,-1,0); DFS2(rt,rt);
while (m--)
{
read(a); read(b); read(t);
for (i=1;i<=a;++i)
read(x),read(y),change(x,y);
for (i=1;i<=b;++i)
read(x),updata(x);
q[++num]=1; q[++num]=n+1;
sort(q+1,q+num+1); num=unique(q+1,q+num+1)-q-1;
for (x=0,i=1;i<num;++i)
x+=sum[q[i]],ans+=x>=t?q[i+1]-q[i]:0;
write(ans); putchar('\n');
for (i=1;i<=num;++i)
sum[q[i]]=0; num=ans=0;
}
return 0;
}
EZ 2018 06 02 NOIP2018 模拟赛(十七)的更多相关文章
- EZ 2018 06 10 NOIP2018 模拟赛(十八)
好久没写blog&&比赛题解了,最近补一下 这次还是很狗的,T3想了很久最后竟然连并查集都忘写了,然后T2map莫名爆炸. Rating爆减......链接不解释 好了我们开始看题. ...
- EZ 2018 06 17 NOIP2018 模拟赛(十九)
这次的题目难得的水,但是由于许多哲学的原因,第二题题意表述很迷. 然后是真的猜题意了搞了. 不过这样都可以涨Rating我也是服了. Upt:链接莫名又消失了 A. 「NOIP2017模拟赛11.03 ...
- EZ 2018 06 24 NOIP2018 模拟赛(二十)
很久之前写的一套题了,由于今天的时间太多了,所以记起来就写掉算了. 这一场尽管T2写炸了,但也莫名Rank4涨了Rating.不过还是自己太菜. A. 环游世界 首先我们先排个序,想一下如果不用走回来 ...
- EZ 2018 03 09 NOIP2018 模拟赛(三)
最近挺久没写比赛类的blog了 链接:http://211.140.156.254:2333/contest/59 这次的题目主要考验的是爆搜+打表的能力 其实如果你上来就把所有题目都看过一次就可以知 ...
- EZ 2018 05 26 NOIP2018 模拟赛(十六)
这次难道就是传说中的标准分大赛?而且这次比赛的链接不翼而飞了 一堆人153pts然后就有Rank4?看来这个Rank4不值钱了,才涨了50+的Rating. 不过还好最后5min的时候想出了T1正解, ...
- EZ 2018 05 20 NOIP2018 模拟赛(十五)
这次的比赛充满着玄学的气息,玄学链接 首先讲一下为什么没有第十四场 其实今天早上9点时看到题目就叫了:原题! 没错,整套试卷都做过,我还写了题解 然后老叶就说换一套,但如果仅仅是这样就没什么 但等13 ...
- EZ 2018 05 13 NOIP2018 模拟赛(十三)
这次的比赛真心水,考时估分240,然后各种悠闲乱逛 然后测完T1数组开小了炸成40,T2,T3都没开long long,T2炸成20,T3爆0 掉回1600+的深渊,但是还有CJJ dalao比我更惨 ...
- EZ 2018 05 04 NOIP2018 模拟赛(十二)
这次的试卷应该是激励我们一下的,链接 然后大家的分数就都很高,然后我就210被一群秒A T2的240大佬爆踩 掉了5rating但Rank竟然发杀了 X_o_r dalao && YZ ...
- EZ 2018 05 01 NOIP2018 模拟赛(十一)
莫名其妙暴涨Rating 其实题目都挺好挺简单的,但是越简单就越容易ZZ 不理解问什么第一题这么多人找环 不过T2是真心细节题,T3太难了 题目戳这里 T1 仔细分析题意发现那个交换规则就是废话,如果 ...
随机推荐
- 安卓开发_数据存储技术_SharedPreferences类
SharedPreferences类 供开发人员保存和获取基本数据类型的键值对. 该类主要用于基本类型,例如:booleans,ints,longs,strings.在应用程序结束后,数据仍旧会保存. ...
- Gradle自动实现Android组件化模块构建
背景 随着App的不断迭代,业务会变得越来越复杂,业务模块会越来越多,且每个模块的代码也会变得越来越多.为了应对这一场景,我们需要把不同的业务模块划分成一个个组件,在修改业务代码的时候只需要在对应模块 ...
- 通过url动态获取图片大小方法总结
很多时候再项目中,我们往往需要先获取图片的大小再加载图片,但是某些特定场景,如用过cocos2d-js的人都知道,在它那里只能按比例缩放大小,是无法设置指定大小的图片的,这就是cocos2d-js 的 ...
- dell r420 H310/H810阵列配置教程及常见问题
进入H310/H810阵列卡BIOS界面 阵列卡管理快捷键 如何创建RAID0和RAID1和RAID5 阵列修复篇 Foreign(外来)状态的硬盘应如何处理 1.进入H310/H810阵列卡BIOS ...
- 【PAT】B1038 统计同成绩学生(20)(20 分)
#include<stdio.h> int arr[102]={0};//分数作为自己的下标,注意 int main(){ int N;scanf("%d",& ...
- nginx 了解一下
先决条件 想要流畅的配置 nginx 需要了解一下内容: 1.nginx 调用方式: 启动 (双击 exe.cmd start nginx .cmd nginx) 使用 (powershell 调用需 ...
- SAP ABAP 如何查找SMOD增强
1.查找程序名 T-CODE:SE93 2.查找开发类 T-code:se38 3.查找SMOD增强 T-CODE:SE16N.表:TADIR 4.查看增强具有哪些功能 T-CODE:SE16N.表: ...
- 使用vue的v-for生成table , 给table加上序号
现在有一个使用mybatis的分页插件生成的table,table中数据是通过vue获得的 , 前台显示使用<tr v-for="item in items"> 后台v ...
- MATLAB用二分法、不动点迭代法及Newton迭代(切线)法求非线性方程的根
MATLAB用二分法.不动点迭代法及Newton迭代(切线)法求非线性方程的根 作者:凯鲁嘎吉 - 博客园http://www.cnblogs.com/kailugaji/ 一.实验原理 二.实验步骤 ...
- book118免费下载文档方法【转】
需要用的工具: 1.360浏览器 2.点"全屏预览",然后把鼠标放在"下载该文档",右键"审查元素",找到 途中箭头指向的标签(如图) 3. ...