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<=109,k<=109,保证所有操作均合法。
分析
讲道理,这个题的正解十分毒瘤。BUT,OJ上有人手贱,于是1s时限变成了10s!!!!!!!!
对的,是10秒
直接给每个点按权值排序,询问时O(n)扫一遍就行了,遇到在矩形内的就记录个数直到遇到第k个就好了,交换时就直接交换。
复杂度为O(nm)
注意,矩形可能给出左上和右下两个端点,也可能给出左下和右上的两个端点。
代码:

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,q[60005],ma[60005];char ch[5];
struct node{int x,y,z;}p[60005];
bool cmp(int a,int b){return p[a].z<p[b].z;}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z),q[i]=i;sort(q+1,q+1+n,cmp);for(int i=1;i<=n;i++)ma[q[i]]=i;for(int i=1;i<=m;i++){scanf("%s",ch+1);if(ch[1]=='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[1]=='Q'){int x1,y1,x2,y2,k,cnt=0,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=1;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[125][125];mar(){memset(a,0,sizeof a);}inline mar operator *(const mar &b)const{mar c;for(int i=1;i<=m;i++)for(int k=1;k<=m;k++)for(int j=1;a[i][k]>=1e-11&&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=0;i<=r;i++)for(int j=1;j<=q;j++){B.a[id(i,j)][id(i+1,j+1)]=p;B.a[id(i,j)][m]=i;//计算每个状态对答案的贡献if(j>1)B.a[id(i,j)][id(0,j-1)]=1.0-p;}int k1=n+1;for(int i=1;i<=m;i++)C.a[i][i]=1.0;//n+1是因为dp[n][j][k]的答案之前没统计到,要多乘一次来统计。while(k1){if(k1&1)C=B*C;B=B*B;k1/=2;}A.a[1][id(0,q)]=1.0;A=A*C;return A.a[1][m]>double(s);
}
int main()
{scanf("%d%d%d%d",&n,&r,&q,&s);double l1=0,r1=1,ans=0;m=(r+1)*q+1;//m就是那个来存答案的编号if(pan(r1)<1e-7){printf("Impossible.");return 0;}while(r1-l1>2*1e-7){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[100005],q[100005];
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<15){for(int i=l;i<r-1;i++)for(int j=i+1;j<r;j++)for(int k=j+1;k<r+1;k++)ansmin=min(ansmin,dis(p[i],p[j],p[k]));return;}    int mid=(l+r)/2,cnt=0,be=1;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-1;i>=l&&abs(p[i].x-p[mid].x)<ansmin;i--)q[++cnt]=p[i];sort(q+1,q+1+cnt,cmp2);for(int i=3;i<=cnt;i++){while(abs(q[be].y-q[i].y)>=ansmin)be++;for(int j=be;j<i-1;j++)for(int k=j+1;k<i;k++)ansmin=min(ansmin,dis(q[i],q[j],q[k]));}
}
int main()
{scanf("%d",&n);addmin=submin=xmin=ymin=ansmin=1<<30;addmax=submax=xmax=ymax=ansmax=-1<<30;for(int i=1;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+1,p+1+n,cmp1);solve(1,n);printf("%d\n%d",ansmax*2,ansmin);
}

中山纪中集训Day2又是测试相关推荐

  1. 中山纪中集训Day2又是测试(划水)

    A组T1 bzoj 2674 Attack Description chnlich 非常喜欢玩三国志这款游戏,并喜欢用一些策略出奇制胜.现在,他要开始征服世界的旅途了.他的敌人有N 座城市和N 个太守 ...

  2. 中山纪中集训游记Day2+8.2模拟赛题解

    Part.I游记 纪中的OJ真的...今天下午又炸一次... 今天模拟赛竟然是考的集训队互测的题...做到自闭... 一开考看见第一题,给我的感觉是要写树套树...然而我不想写... 然后就去看了第二 ...

  3. 2019寒假纪中集训总结学期总结(流水账)

    学期总结 这学期上了初三,学校的初.高中校区对调,我们的班主任也由一个生物老师换成了一个化学老师. 之前的班主任比较年轻,跟我们这群学生有这很好的感情,亦师亦友,陪伴我们度过了几乎没有中考压力的初一. ...

  4. [2021.8纪中集训Day14]

    文章目录 1312. 老曹的忧郁 题目 思路 代码 1313. 老曹骑士 题目 思路 代码 1314. 稳定的数字 题目 思路 代码 封锁阳光大学 题目 题目描述 输入格式 输出格式 输入输出样例 说 ...

  5. 纪中集训2020.01.13【NOIP普及组】模拟赛C组总结————My First Time Write Summary

    纪中集训2020.01.13[NOIP普及组]模拟赛C组总结 题目编号 标题 0 [NOIP普及组模拟]取值( numbers.pas/cpp) 1 [NOIP普及组模拟]数对(pairs.pas/c ...

  6. 纪中集训2020.01.16【NOIP普及组】模拟赛C组总结+【0.Matrix】分析

    纪中集训2020.01.16[NOIP普及组]模拟赛C组总结+[0.Matrix]分析 题目: 0.matrix 1.product 2.binary 3.value 巨佬估分:100+100+40+ ...

  7. 2018纪中集训游记

    DAY  0 从家出发的时候,阴天了,开始祈祷不要下雨(之后貌似起飞的时候下了大雨,不过当时在云层里只感觉到了一丢丢颠簸?) 飞机给咕咕了半个小时,期间一直在被老头子呵斥不要奶飞机,我一直在叨叨:飞机 ...

  8. 2019纪中集训总结

    其实用一句话总结的话,那么就是: We still have a long way to go. 来到纪中,才知道全国还有这么多优秀的OI神犇,才知道自己不过是井下之蛙,才知道自己之前的幼自满的幼稚. ...

  9. 中山纪中训练游记Day1+8.1模拟赛题解

    Part.I游记 纪中的电脑真好,开个资源监视器就蓝屏了(插上U盘也有蓝屏).我... (F**k 纪中的OJ怎么和CCF的这么像? 上午比赛做第一题的时候用并查集判断是否是同一个连通块的时候把并查集 ...

最新文章

  1. 6425C-Lab2 安全高效地管理AD
  2. 斗地主程序设计c语言,C语言斗地主游戏v0.1
  3. 【文档】软件版本发布说明
  4. C# in Depth-类型系统的特征
  5. Kafka单机、集群模式安装详解(二)
  6. 交换两个变量的值(4种方法)
  7. 敏捷开发智慧敏捷系列之三:做不做架构设计?
  8. error C3646: “noexcept”: 未知重写说明符_三个世纪以来首次发现:大脑中还藏着一种未知的器官?...
  9. 用到f6的快捷键_让你的办公效率成倍翻得快捷键。
  10. JavaEE学习12--JDBC(上)
  11. WinHTTP实现文件下载 C++程序
  12. jquery输入框日历时间插件
  13. 【Funpack】蓝牙技术 QA
  14. 2021-05-21 Matlab实现快速傅里叶逆变换
  15. Brocade 6510 交换机清空配置,重新initiator交换机
  16. tex插入excel图表_Excel:以编程方式插入图表。
  17. CDH的安装详细步骤
  18. Python打卡四——字符串讲解
  19. pillow库,PIL库
  20. 教你批量将视频画面顺时针旋转90度

热门文章

  1. 连续型随机变量及其常见分布的分布函数和概率密度
  2. java 面向对象之构造器:
  3. 价格敏感型消费者 | 画饼系列
  4. RocketMQ 顺序消息解析——图解、源码级解析
  5. java单元测试 规范,java – 在spock单元测试规范中传递实际参数
  6. 传递爱心 温暖每一个孩子
  7. 华为OD机试题,用 Java 解【英文输入法】问题
  8. Matlab保存图片的几种方法
  9. java语言:创建一个二维数组,将古诗《春晓》的内容赋值于二维数组,然后分别用横版和竖版两种方式输出。
  10. 统计思维(实例11)——时间序列分析