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 仔细分析题意发现那个交换规则就是废话,如果 ...
随机推荐
- Python 解决Python安装包时提示Unable to find vcvarsall.bat的问题
解决Python安装包时提示Unable to find vcvarsall.bat的问题 by:授客 QQ:1033553122 问题 Python安装包时,提示Unable to find v ...
- MSSQL一种取代游标的方案
今天看到一篇文章写的自己整理记录下,据说比用游标快. DECLARE @字段1 数据类型; DECLARE @字段2 数据类型; DECLARE @TMP_WHILE_ID INT; ,),TMP_W ...
- pyenv离线安装python各版本
1.问题描述: 可能是国内的网络原因,在线用pyenv安装python老是定住没反应 [root@zabbix ~]# pyenv install Downloading Python-.tar.xz ...
- MySQL 1130 - Host 127.0.0.1 is not allowed to connect to this MySQL server
在开发中为了让开发更方便,在本地配置环境,希望可以直接访问服务器上的MySQL数据库,更方便的管理数据库, 需要在本地远程连接linux服务器的本地数据库,直接用数据库管理工具连接出现如下报错1130 ...
- SqlBulkCopy批量添加
/// <summary> /// 添加数据 /// 注:DataTable列名必须和数据库列名一致 /// </summary> /// <returns>< ...
- React框架简介
React的基本认识 Facebook开源的一个js库,一个用来动态构建用户界面的js库 英文官网,中文官网 React的特点 Declarative(声明式编码),Component-Based(组 ...
- 简单规划dp sumsets
Farmer John commanded his cows to search for different sets of numbers that sum to a given number. T ...
- 洛谷P1223
#include <iostream>#include <algorithm>#include <cstdio>using namespace std;int b[ ...
- javascript获取指定区间范围随机数的方法
每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code //获取指定区间范围随机数,包括lowerValue和upperValue funct ...
- 阿里巴巴android开发手册总结
每天学习一点点 编程PDF电子书免费下载: http://www.shitanlife.com/code 1 2. 3. 4. 5. 6. 7. 8. 9 每天学习一点点 编程PDF电子书免费 ...