中山纪中集训Day2又是测试(划水)
A组T1 bzoj 2674 Attack
Description
chnlich 非常喜欢玩三国志这款游戏,并喜欢用一些策略出奇制胜。现在,他要开始征服世界的旅途了。他的敌人有N 座城市和N 个太守, N个城市可以看作在二维平面上的N 个点。N 座城市的标号为0,1,2,......,N-1。第i 座城市的坐标为(Xi,Yi),镇守这座城市的太守的能力值为Zi。
chnlich 每次会选择一个边平行于坐标轴的矩形区域,并奇袭其中太守能力值第K小的城市(奇袭结束之后城市与太守依然存在)。
不过,他的敌人经常会偷偷交换两座城市的太守,防止弱点被chnlich 发现。
现在,chnlich 想要知道,每次奇袭时他的敌人的能力值。
Input
输入的第一行包含两个整数 N,M,N 表示城市与太守的个数,M 表示接下来发生了 M 个事件。
输入的第二行到第 N+1行,每行包含三个整数,第 i+2行的三个整数依次表示编号为 i 的城市的 Xi,Yi,Zi,含义如题所述。
输入的第 N+2行到第 N+M+1行,每行有两种可能形式:
第一种
QUERY x0 y0 x1 y1 k
表示 chnlich 询问一个相对顶点为(x0,y0),(x1,y1)的矩形中,第 k 小能力值太
守的能力值。
第二种
SWAP x y
表示 chnlich 的敌人交换了编号为 x 和 y 两座城市的太守。
Output
对于每一个 QUERY,输出一行。
若不存在第 k 小能力值的太守,输出"It doesn't exist."(不包含引号)。
否则输出一个整数,表示矩形内能力值第 k 小太守的能力值。
Sample Input
3 5
1 1 1
2 2 2
3 3 3
QUERY 1 1 3 3 3
SWAP 0 1
QUERY 2 2 4 4 1
SWAP 2 2
QUERY 2 2 3 3 3
Sample Output
3
1
It doesn't exist.
Data Constraint
Hint
对于100%的数据,N<=60000,M<=10000,0<=Xi,Yi,Zi<=10^9,k<=10^9,保证所有操作均合法。
分析
讲道理,这个题的正解十分毒瘤。BUT,OJ上有人手贱,于是1s时限变成了10s!!!!!!!!
对的,是10秒
直接给每个点按权值排序,询问时O(n)扫一遍就行了,遇到在矩形内的就记录个数直到遇到第k个就好了,交换时就直接交换。
复杂度为O(nm)
注意,矩形可能给出左上和右下两个端点,也可能给出左下和右上的两个端点。
代码:
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,q[],ma[];char ch[];
struct node{int x,y,z;}p[];
bool cmp(int a,int b){return p[a].z<p[b].z;}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z),q[i]=i;
sort(q+,q++n,cmp);
for(int i=;i<=n;i++)ma[q[i]]=i;
for(int i=;i<=m;i++)
{
scanf("%s",ch+);
if(ch[]=='S')
{
int a,b;
scanf("%d%d",&a,&b);a++;b++;
swap(q[ma[a]],q[ma[b]]);swap(p[a].z,p[b].z);
swap(ma[a],ma[b]);
}
if(ch[]=='Q')
{
int x1,y1,x2,y2,k,cnt=,ans;
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&k);
if(x1>x2)swap(x1,x2);
if(y1>y2)swap(y1,y2);
for(int i=;i<=n&&cnt<k;i++)
if(x1<=p[q[i]].x&&p[q[i]].x<=x2&&y1<=p[q[i]].y&&p[q[i]].y<=y2)
{cnt++;if(cnt==k){ans=q[i];break;}}
if(cnt<k)printf("It doesn't exist.\n");
else printf("%d\n",p[ans].z);
}
}
}
A组T2 bzoj 2676 Contra
Description
偶然间,chnlich 发现了他小时候玩过的一个游戏“魂斗罗”,于是决定怀旧。但是这是一个奇怪的魂斗罗 MOD。
有 N 个关卡,初始有 Q 条命。
每通过一个关卡,会得到 u 分和1条命,生命上限为 Q。其中 u=min(最近一次连续通过的关数,R)。
若没有通过这个关卡,将会失去1条命,并进入下一个关卡。
当没有生命或没有未挑战过的关卡时,游戏结束,得到的分数为每关得到的分数的总和。
由于 chnlich 好久不玩这个游戏了,每条命通过每个关卡的概率均为p(0<=p<=1),原先 chnlich 的最高分纪录是 S。
现在 chnlich 想要知道,当 p 至少为多少时,chnlich 期望获得的总分数能够超过原先的最高分。
Input
输入共一行,分别表示整数 N,整数 R,整数 Q,原先的最高分整数 S。
Output
输出共一行,若不存在这样的 p,输出"Impossible."(不包含引号),否则输出 p(保留6位小数)。
Sample Input
【样例输入一】
4 2 1 5
【样例输入二】
12 3 2 12
Sample Output
【样例输出一】
0.880606
【样例输出二】
0.687201
Data Constraint
Hint【数据说明】
对于20%的数据,N<=15
对于50%的数据,N<=10000
对于100%的数据,N<=10^8,1<=R<=20,1<=Q<=5,保证 S 是一个可能出现的分数。
【补充说明】
补充说明】
例如,当 N=12,R=3,Q=2时
第一关:未通过 u=0 获得分数0 总分为0 剩余生命1
第二关:通过 获得分数1 总分为1 剩余生命2
第三关:通过 获得分数2 总分为3 剩余生命2
第四关:通过 获得分数3 总分为6 剩余生命2
第五关:通过 获得分数3 总分为9 剩余生命2
第六关:未通过 获得分数0 总分为9 剩余生命1
第七关:通过 获得分数1 总分为10 剩余生命2
第八关:未通过 获得分数0 总分为10 剩余生命1
第九关:未通过 获得分数0 总分为10 剩余生命0
游戏结束 总分为10
这是 chnlich 游戏的一种可能性
假装分析
显然这是一道期望题(废话)。二分一下概率p,然后看dp出来的期望值是否比s大。
设dp[i][j][k]表示已经过了i关,连胜了j次,还剩下k条命的概率。
那么dp[i][j][k]就可以转移到dp[i+1][0][k-1](失败)和dp[i+1][min(j+1,r)][min(k+1,q)](成功)。(取min是因为超过了限制的状态贡献相同,可以合在一起)
则dp[i+1][0][k-1]+=dp[i][j][k]*(1-p),dp[i+1][min(j+1,r)][min(k+1,q)]+=dp[i][j][k]*p。
如何求期望值呢?
因为期望是可以分开求的,所以,每个状态dp[i][j][k]的贡献就是dp[i][j][k]*j,加起来就好啦。
不过这样是会TLE的,要用矩阵加速。
如果就直接拿来加速不好写,所以将j与k拿过来压成一个状态就行了,给每种(j,k)编个号。
另外还要一边乘一边计算答案,只需要修改一下矩阵,拿一个没用的编号来存答案即可。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define id(a,b) (min(a,r)*q+min(b,q))
using namespace std;
int n,m,q,r,s;
struct mar
{
double a[][];mar(){memset(a,,sizeof a);}
inline mar operator *(const mar &b)const
{
mar c;
for(int i=;i<=m;i++)for(int k=;k<=m;k++)for(int j=;a[i][k]>=1e-&&j<=m;j++)
c.a[i][j]+=a[i][k]*b.a[k][j];
return c;
}
};
inline bool pan(double p)
{
mar A,B,C;B.a[m][m]=1.0;//将之前的答案传递下来
for(int i=;i<=r;i++)for(int j=;j<=q;j++)
{
B.a[id(i,j)][id(i+,j+)]=p;
B.a[id(i,j)][m]=i;//计算每个状态对答案的贡献
if(j>)B.a[id(i,j)][id(,j-)]=1.0-p;
}
int k1=n+;for(int i=;i<=m;i++)C.a[i][i]=1.0;//n+1是因为dp[n][j][k]的答案之前没统计到,要多乘一次来统计。
while(k1){if(k1&)C=B*C;B=B*B;k1/=;}
A.a[][id(,q)]=1.0;A=A*C; return A.a[][m]>double(s);
}
int main()
{
scanf("%d%d%d%d",&n,&r,&q,&s);
double l1=,r1=,ans=;m=(r+)*q+;//m就是那个来存答案的编号
if(pan(r1)<1e-){printf("Impossible.");return ;}
while(r1-l1>*1e-)
{
double mid=(l1+r1)*0.5;
if(pan(mid))ans=mid,r1=mid;
else l1=mid;
}
printf("%.6lf",l1);
}
A组T3 bzoj 2675 Bomb
Description
A 国和 B 国是两个超级大国,长期处于冷战状态;
A 国在 B 国中设有 N 个情报站,编号为 1,2,3, …… ,N ,每个情报站有一个坐标 (Xi,Yi) 。但是, A 国的工作人员发现,每个情报站里都被埋上了炸弹!
这些炸弹非常特殊 , 只要同时拆除其中的三个炸弹 , 所有炸弹就都不会爆炸了。
由于各个情报站联络需要代价 , 拆除炸弹需要花费的总代价为这些炸弹两两之间的曼哈顿距离和。
现在 A 国的指挥部门找到了你 , 希望知道可能需要的最大代价和最小代价 。
Input
输入的第一行包含一个整数 N 。接下来 N 行,第 i+1 行两个整数 Xi,Yi ,表示第 i 个情报站的坐标。
Output
输出两行 , 每行包含一个整数 , 第一行表示可能的最大代价 , 第二行表示可能的最小代价。
Sample Input
4
1 1
1 2
2 1
2 3
Sample Output
6
4
Data Constraint
Hint
对于 30% 的数据, N<=500
对于另外 10% 的数据,每个点出现至少两遍
对于 50% 的数据, N<=1000
对于 60% 的数据, N<=8000
对于 70% 的数据, N<=15000
对于 80% 的数据, N<=50000
对于 100% 的数据, N<=100000 , 0<=Xi,Yi<=10^8
【 注释 】
对于两个点 (X0,Y0),(X1,Y1) ,
它们之间的曼哈顿距离为 abs(X0-X1)+abs(Y0-Y1) 。
抄题解的分析
先来看最大值(接下来是题解):
我们考虑三个点两两之间的曼哈顿距离和的实质。通过画图, 我们容易发现,问题的实质是求能包含这三个点的最小矩形的周长,即 2*(Xmax-Xmin+Ymax-Ymin),因此我们只要最大化和最小化 Xmax-Xmin+Ymax-Ymin 即可。 考虑这四个未知量,显然,一个点最多确定一个 X 未知量和一个 Y 未知量,答案的组成可 能有两种情况:
①一个点确定了一个 X 和一个 Y,另外两个点分别确定了一个 X 和一个 Y。
②一个点确定了一个 X 和一个 Y,另一个点同样确定了一个 X 和一个 Y,还有一个点 什么都没有确定(但必须存在这个点)。
我们分别考虑这两种情况。先考虑最大值。显然,确定最大值的点一定在 Xmax+Ymax,-Xmin+Ymax,-Xmin-Ymin,Xmax-Ymin,Xmin,Xmax,Ymin,Ymax 最大的至多 8个 点中选择三个,因此只需选出能使这些值变得最大的点暴力即可。
个人理解就是把曼哈顿距离的绝对值展开来进行维护,以X+Y的最大值为例,它能保证我们在这里取了一个点。用它减去X与Y的最小值。若X与Y的最小值属于同一个点,那么就是情况②,若不属于同一个点就是情况①。
再来看看最小值
本来最小值我打算想写线段树的,但网上一两百行的代码直接把我劝退了。于是又去找了一种分治的做法。可为什么我怎么看都像暴力加剪枝?
按照x排序后就直接分治,若点数小于15就直接暴力。合并的时候将两边距离中点距离小于当前最小答案的点拿出来,再按y值排序,再次暴力即可,如果一个点与另一个点的y值之差大于等于当前最小答案那么也要舍去。
代码:
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int addmax,addmin,submax,submin,xmax,xmin,ymax,ymin,ansmax,ansmin;
struct node{int x,y;}p[],q[];
bool cmp1(node a,node b){return a.x==b.x?a.y<b.y:a.x<b.x;}
bool cmp2(node a,node b){return a.y==b.y?a.x<b.x:a.y<b.y;}
int dis(node a,node b,node c){return abs(a.x-b.x)+abs(a.y-b.y)+abs(a.x-c.x)+abs(a.y-c.y)+abs(b.x-c.x)+abs(b.y-c.y);}
void solve(int l,int r)
{
if(r-l<)
{
for(int i=l;i<r-;i++)for(int j=i+;j<r;j++)for(int k=j+;k<r+;k++)
ansmin=min(ansmin,dis(p[i],p[j],p[k]));return;
}
int mid=(l+r)/,cnt=,be=;solve(l,mid);solve(mid,r);
for(int i=mid;i<=r&&abs(p[i].x-p[mid].x)<ansmin;i++)q[++cnt]=p[i];
for(int i=mid-;i>=l&&abs(p[i].x-p[mid].x)<ansmin;i--)q[++cnt]=p[i];
sort(q+,q++cnt,cmp2);
for(int i=;i<=cnt;i++)
{
while(abs(q[be].y-q[i].y)>=ansmin)be++;
for(int j=be;j<i-;j++)for(int k=j+;k<i;k++)
ansmin=min(ansmin,dis(q[i],q[j],q[k]));
}
}
int main()
{
scanf("%d",&n);
addmin=submin=xmin=ymin=ansmin=<<;
addmax=submax=xmax=ymax=ansmax=-<<;
for(int i=;i<=n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
xmax=max(xmax,p[i].x);ymax=max(ymax,p[i].y);
xmin=min(xmin,p[i].x);ymin=min(ymin,p[i].y);
addmax=max(addmax,p[i].x+p[i].y);addmin=min(addmin,p[i].x+p[i].y);
submax=max(submax,p[i].x-p[i].y);submin=min(submin,p[i].x-p[i].y);
}
ansmax=max(ansmax,addmax-xmin-ymin);ansmax=max(ansmax,xmax+ymax-addmin);
ansmax=max(ansmax,submax-xmin+ymax);ansmax=max(ansmax,xmax-ymin-submin);
sort(p+,p++n,cmp1);solve(,n);
printf("%d\n%d",ansmax*,ansmin);
}
中山纪中集训Day2又是测试(划水)的更多相关文章
- 「中山纪中集训省选组D1T1」最大收益 贪心
题目描述 给出\(N\)件单位时间任务,对于第\(i\)件任务,如果要完成该任务,需要占用\([S_i, T_i]\)间的某个时刻,且完成后会有\(V_i\)的收益.求最大收益. 澄清:一个时刻只能做 ...
- 中山纪中集训Day4双是测试(划沝) 九校联考-DL24凉心模拟Day2
A组T1 锻造 (forging) 1.1 题目背景 勇者虽然武力值很高,但在经历了多次战斗后,发现怪物越来越难打于是开始思考是不是自己平时锻炼没到位,于是苦练一个月后发现......自己连一个史莱姆 ...
- 中山纪中集训Day5叒是测试(划淼)
A组T1 矩阵游戏(game) 九校联考24OI__D1T1 问题描述 LZK发明一个矩阵游戏,大家一起来玩玩吧,有一个N行M列的矩阵.第一行的数字是1,2,…M,第二行的数字是M+1,M+2…2*M ...
- 中山纪中集训Day1测试(摸鱼)
AT3 粉刷匠 Description 赫克托是一个魁梧的粉刷匠,而且非常喜欢思考= = 现在,神庙里有N根排列成一直线的石柱,从1到N标号,长老要求用油漆将这些石柱重新粉刷一遍.赫克托有K桶颜色各不 ...
- 「中山纪中集训省选组D4T1」折射伤害 高斯消元
题目描述 在一个游戏中有n个英雄,初始时每个英雄受到数值为ai的伤害,每个英雄都有一个技能"折射",即减少自己受到的伤害,并将这部分伤害分摊给其他人.对于每个折射关系,我们用数对\ ...
- 「中山纪中集训省选组D2T1」书堆 欧拉常数
题目描述 蚂蚁是勤劳的动物,他们喜欢挑战极限.现在他们迎来了一个难题!蚂蚁居住在图书馆里,图书馆里有大量的书籍.书是形状大小质量都一样的矩形.蚂蚁要把这些书摆在水平桌子的边缘.蚂蚁喜欢整洁的布置,所以 ...
- 纪中集训 Day1
今天早上起来吃饭,发现纪中伙食真的是太差了!!!什么都不热,早餐的面包还好,然后就迎来了美好的早晨= = 早上做一套题,T1T2果断秒,T3一看就是noi原题,还好看过题解会写,然后就愉快的码+Deb ...
- 纪中集训 Day 2
今天(其实是昨天= =)早上起来发现好冷好冷啊= = 吃完饭就准备比赛了,好吧B组难度的题总有一道不知到怎么写QAQ 太弱了啊!!! 蒟蒻没人权啊QAQ 今天第4题不会写,在这里说说吧 题目的意思就是 ...
- 纪中集训 Day 0?
好吧昨天的等到今天才来写,现在超不想刷题,来写下blog吧= = 坐了近10H的火车终于来到了中山市 火车上在看空之境界,等有时间补下动画吧= = 到了宿舍各种不习惯(现在才发现还是母校好QAQ)然后 ...
随机推荐
- BUAAOO-Final-Summary
目录 总结本单元两次作业的架构设计 总结自己在四个单元中架构设计及OO方法理解的演进 总结自己在四个单元中测试理解与实践的演进 总结自己的课程收获 立足于自己的体会给课程提三个具体改进建议 两次架构设 ...
- 【转载】JVM结构、GC工作机制详解
文章主要分为以下四个部分 JVM结构.内存分配.垃圾回收算法.垃圾收集器.下面我们一一来看. 一.JVM结构 根据<java虚拟机规范>规定,JVM的基本结构一般如下图所示: 从左图可知, ...
- 汇总iOS开发中需要用到的开源库
来源:http://mobile.51cto.com/hot-431256.htm 1.iOS &iPhone 网络异步加载 asi-http-request [1-1 ASI HTTP 下载 ...
- Centos7 docker安装GitLab
*先决条件系统已安装Docker 1.查询GitLab镜像 docker search gitlab 2.现在GitLab镜像 3.创建文件夹 mkdir -p /software/gitlab/co ...
- Flume 初探
Apache 是一个高可用.高可靠的,分布式的海量日志采集.聚合.传输系统,基于流式架构,灵活简单. Flume 最主要的作用就是实时读取服务器本地磁盘的数据,将数据写入HDFS中. Flume组成架 ...
- Computer Vision_33_SIFT:Fast Adaptive Bilateral Filtering——2018
此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...
- Schema学习【一】
XML Schema 是基于 XML 的 DTD 替代者. 什么是 XML Schema? XML Schema 的作用是定义 XML 文档的合法构建模块,类似 DTD. XML Schema: 定义 ...
- 安装k8s,使用root帐号的初始化脚本
现在稳定性差不多了.可以总结一下了. 真正使用时,有几个地方,还是确认一下,再正式运行吧. #!/bin/bash # Version V0. ---: ;fi K8S_VERSION="1 ...
- Python 利用random库来实现圆周率的运算
蒙特卡罗方法求解圆周率 随机向一个正方形以及其内切圆(半径为1)的图形中随机抛洒大量的点,计算每个点到圆心的距离从而判断该点在圆内或圆外,用圆内的点除以总点数就是π/4的值.点数越多,值就越精确. 具 ...
- LG2664 树上游戏
树上游戏 题目描述 lrb有一棵树,树的每个节点有个颜色.给一个长度为n的颜色序列,定义s(i,j) 为i 到j 的颜色数量.以及 $$sum_i=\sum_{j=1}^ns(i,j)$$ 现在他想让 ...