2021.05.29【NOIP提高B组】模拟 总结
T1
题意:给你一个图,可以不花代价经过 \(K\) 条边,问从起点到终点的最短路
考试的想法:设 \(dis_{i,j}\) 表示从起点免费了 \(j\) 条边到 \(i\) 的最短路
然后直接跑 \(\text{spfa}\)
结果:\(WA\)
正解:分层图,需要考虑去到下一层就不能回来的情况
分为 \(K\) 层,同一层的 \(u,v\) 边权不变,双向边,去下一层的单向边,权值为 0
然后 \(\text{spfa}\) 超时,用 \(\text{dijkstra}\) 即可
答案:免费任意次的最小值
#include<bits/stdc++.h>
using namespace std;
const int N=10005,M=50005;
int n,m,K,S,T,vis[N*12],ans=2100000000;
int lst[N*12],nxt[M<<6],to[M<<6],qz[M<<6],dis[N*12],cnt;
inline void Ae(int fr,int go,int vl) {
to[++cnt]=go,qz[cnt]=vl,nxt[cnt]=lst[fr],lst[fr]=cnt;
}
struct node {
int v,id;
node(int x,int y):v(x),id(y) {}
bool operator<(node x) const
{ return v>x.v; }
};
priority_queue<node> q;
inline void dijkstra() {
memset(dis,100,sizeof(dis));
dis[S]=0;
q.push(node(0,S));
register int u;
while(!q.empty()) {
u=q.top().id,q.pop();
if(vis[u])continue; vis[u]=1;
for(int i=lst[u],v;i;i=nxt[i])
if(dis[v=to[i]]>dis[u]+qz[i]) {
dis[v]=dis[u]+qz[i];
q.push(node(dis[v],v));
}
}
}
int main() {
scanf("%d%d%d%d%d",&n,&m,&K,&S,&T);
++S,++T;
for(int i=1,u,v,w;i<=m;i++) {
scanf("%d%d%d",&u,&v,&w);
++u,++v,Ae(u,v,w),Ae(v,u,w);
for(int j=1;j<=K;j++) {
Ae(u+j*n,v+j*n,w);
Ae(v+j*n,u+j*n,w);
Ae(u+j*n-n,v+j*n,0);
Ae(v+j*n-n,u+j*n,0);
}
}
dijkstra();
for(int i=0;i<=K;i++)
ans=min(ans,dis[T+n*i]);
printf("%d",ans);
}
T2
题目大意:给你许多条平行于 \(x\) 轴或 \(y\) 轴的线段
问你最大的十字架大小,大小为 \(R\) 定义为从一个点按上下左右伸出 \(R\) 都有线段覆盖
没有十字架输出 Human intelligence is really terrible
考试时:把所有线段合起来再暴力匹配
结果:看错题了:不会有两条共线线段有交点
正解:可以二分大小 \(R\) ,若把所有线段左右(或上下)都减去 \(R\) 还有线段相交则 \(R\) 成立
所以判断是否有线段相交,用扫描线
T3
题意:找出图中平均值最小的环,无环输出 PaPaFish is laying egg!
考试的想法:二分答案,然后用 \(\text{spfa}\) 一波复杂的操作
正解:把所有边权减去 \(mid\) 若有负环说明 \(mid\) 可以
#include<bits/stdc++.h>
using namespace std;
typedef double db;
const db eps=1e-3;
const int N=1005,M=10005;
int n,m,cnt,lst[N],nxt[M],to[M],vis[N];
db l,r,mid,ans=-1,qz[M],d[N],flg;
inline void Ae(int fr,int go,int vl) {
to[++cnt]=go,qz[cnt]=1.0*vl;
nxt[cnt]=lst[fr],lst[fr]=cnt;
}
void spfa(int u) {
vis[u]=1;
for(int i=lst[u],v;i;i=nxt[i])
if(d[u]+qz[i]-mid<d[v=to[i]]) {
d[v]=d[u]+qz[i]-mid;
if(vis[v])flg=1;
else spfa(v);
if(flg)return;
}
vis[u]=0;
}
inline bool chk() {
memset(d,0,sizeof(d));
memset(vis,0,sizeof(vis));
flg=0;
for(int i=1;i<=n;i++)
if(!d[i]) {
spfa(i);
if(flg)return 1;
}
return 0;
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1,u,v,w;i<=m;i++) {
scanf("%d%d%d",&u,&v,&w);
Ae(u,v,w);
}
r=10000000;
while(l+0.000001<r) {
mid=(l+r)/2.0;
if(chk())ans=r=mid;
else l=mid;
}
if(ans==-1)puts("PaPaFish is laying egg!");
else printf("%.2lf",floor(ans*1000)/1000);
}
T4
题目大意:给你一个排列,求字典序比他大的第一个与他逆序对数一样的排列
考试:直接树状数组+\(\text{next_permutation}\),光荣 30
正解:观察样例可以发现有一段是不变的,考虑找到最大的这个下标
设 \(Nx(i)\) 为 \(a_i,a_{i+1},a_{i+2},\cdots,a_{n}\) 的逆序对个数
则这个点要满足
- 后面有个数比他大
- 这个数对后面的数的逆序对小于 \(Nx(i)\)
找到后开始构造,设总共有 \(all\) 个逆序对
发现这个点的数是后面中他的后继,于是 \(ans_{p}\) 填好了
然后现在我们已经有(前面一部分逆序对数)+(\(ans_p\)对后面一部分的逆序对数)个逆序对,记为 \(sum\)
填剩下的位置,发现若 (填 \(i\) 产生的逆序对数)+(原有的 \(sum\))+(剩下最大逆序对数)\(\ge all\),则合法
好像可以二分,于是加一个权值线段树查找第 \(k\) 大即可。每次查询要更新 \(sum\)
#include<bits/stdc++.h>
#define G getchar
#define P putchar
using namespace std;
inline int rd() {
register int x=0,f=1;
char C=getchar();
for(;C<'0'||C>'9';C=G())f&=C^45;
for(;C>'/'&&C<':';C=G())x=(x<<1)+(x<<3)+(C^48);
return f?x:-x;
}
void put(int x) { if(x>9)put(x/10); P(x%10|48); }
typedef long long LL;
const int N=500005;
int n,x[N],pos,mx,y[N],l,r,mid,out;
LL t[N],all,nx[N],val[N<<2],sum;
inline LL MX(LL x) { return x*(x-1)/2; }
inline void add(int p,int v) { for(;p<=n;p+=p&-p)t[p]+=1LL*v; }
inline LL ask(LL p) { register LL s=0; for(;p;p-=p&-p)s+=t[p]; return s; }
#define ls rt<<1
#define rs rt<<1|1
void mdy(int p,int v,int l,int r,int rt) {
if(l==r) { val[rt]+=v; return; }
register int mid=l+r>>1;
if(p<=mid)mdy(p,v,l,mid,ls);
else mdy(p,v,mid+1,r,rs);
val[rt]=val[ls]+val[rs];
}
int fnd(int k,int l,int r,int rt) {
if(l==r)return l;
register int mid=l+r>>1;
if(k<=val[ls])return fnd(k,l,mid,ls);
else return fnd(k-val[ls],mid+1,r,rs);
}
#undef ls
#undef rs
int main() {
n=rd();
for(int i=1;i<=n;i++)x[i]=rd();
for(int i=n;i;i--) {
add(x[i],1),nx[i]=ask(x[i]-1);
all+=nx[i];
}
mx=x[n],sum=nx[n];
for(int i=n-1;i;i--) {
mx=max(mx,x[i]),sum+=nx[i];
if(x[i]^mx && nx[i]<sum) {
pos=i; break;
}
}
sum=0;
for(int i=1;i<pos;i++)put(x[i]),P(32),sum+=nx[i];
out=INT_MAX;
for(int i=pos+1;i<=n;i++)
if(x[i]>x[pos])out=min(out,x[i]);
put(out),P(32);
for(int i=pos;i<=n;i++)
if(x[i]^out)mdy(x[i],1,1,n,1),sum+=(x[i]<out);
for(int i=pos+1;i<=n;i++) {
l=1,r=n-i+1;
while(l<r) {
mid=l+r>>1;
if(mid-1+sum+MX(n-i)>=all)
r=mid;
else l=mid+1;
}
out=fnd(l,1,n,1),put(out),P(32);
sum+=l-1,mdy(out,-1,1,n,1);
}
}
总结
这些题我该怎么想:
T1:遇到图论不能单纯设状态,最好连边
T2:认真看题+二分的运用+扫描线的题型
T3:遇到环上值的题多想想负环,同时了解图的边权是可以变的
T4:贪心策略一直不强,逆序对的构造要了解,同时多观察样例
总结:最近的题知识点普遍不少,需要好好消化
2021.05.29【NOIP提高B组】模拟 总结的更多相关文章
- 5820. 【NOIP提高A组模拟2018.8.16】 非法输入(模拟,字符串)
5820. [NOIP提高A组模拟2018.8.16] 非法输入 (File IO): input:aplusb.in output:aplusb.out Time Limits: 1000 ms ...
- JZOJ 5818. 【NOIP提高A组模拟2018.8.15】 做运动
5818. [NOIP提高A组模拟2018.8.15] 做运动 (File IO): input:running.in output:running.out Time Limits: 2000 ms ...
- JZOJ 5812. 【NOIP提高A组模拟2018.8.14】 区间
5812. [NOIP提高A组模拟2018.8.14] 区间 (File IO): input:range.in output:range.out Time Limits: 1000 ms Memo ...
- 2021.06.05【NOIP提高B组】模拟 总结
T1 题意:给你一个 \(n\) 个点 \(n\) 条边的有向图, 求每个店经过 \(K\) 条边后的边权和.最小边权 \(K\le 10^{10}\) 考试时:一直想着环,结果一直不知道怎么做 正解 ...
- 2021.05.05【NOIP提高B组】模拟 总结
T1 给你一棵树,要求增加最少的边权是的从根到每一个叶子的长度相等 不能改变原有的最大长度 这是一个贪心:尽可能往深度小的边增加 先预处理出 \(mx_i\) 表示从 \(i\) 到叶子的最大长度 然 ...
- [JZOJ5817] 【NOIP提高A组模拟2018.8.15】 抄代码
Description J 君是机房的红太阳,每次模拟她总是 AK 虐场.然而在 NOIP2117 中,居然出现了另一位 AK 的选手 C 君! 这引起了组委会的怀疑,组委会认为 C 君有抄袭 J 君 ...
- [JZOJ5818] 【NOIP提高A组模拟2018.8.15】 做运动
Description 一天,Y 君在测量体重的时候惊讶的发现,由于常年坐在电脑前认真学习,她的体重有了突 飞猛进的增长. 幸好 Y 君现在退役了,她有大量的时间来做运动,她决定每天从教学楼跑到食堂来 ...
- 【NOIP提高A组模拟2018.8.14】 区间
区间加:差分数组修改 O(n)扫描,负数位置单调不减 #include<iostream> #include<cstring> #include<cstdio> # ...
- [jzoj 5782]【NOIP提高A组模拟2018.8.8】 城市猎人 (并查集按秩合并+复杂度分析)
传送门 Description 有n个城市,标号为1到n,修建道路花费m天,第i天时,若gcd(a,b)=m-i+1,则标号为a的城市和标号为b的城市会建好一条直接相连的道路,有多次询问,每次询问某两 ...
- [jzoj 5781]【NOIP提高A组模拟2018.8.8】秘密通道 (最短路)
传送门 Description 有一副nm的地图,有nm块地,每块是下列四种中的一种: 墙:用#表示,墙有4个面,分别是前面,后面,左面,右面. 起点:用C表示,为主角的起点,是一片空地. 终点:用F ...
随机推荐
- JavaScript遍历表单元素
运行效果: 源代码: 1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta char ...
- spatialite-tools 安装
spatialite-tools 安装 官网 https://www.gaia-gis.it/fossil/spatialite-tools/index 下载地址 https://www.gaia-g ...
- echarts饼图禁止鼠标悬浮高亮
将高亮时的颜色和原本颜色手动设置成相同的值,把series.data里的itemStyle属性进行设置 代码如下: option = { color:['#3498db','#EEEEEE'], se ...
- C语言结构体指针与结构体变量作形参的区别
区别 结构体变量 结构体变量作为形参,传递的是结构体变量本身,是一种值传递 形参结构体变量成员值的改变不影响对应的实参构体变量成员值的改变 结构体指针 结构体指针作为函数参数,传递的是指向结构体变量的 ...
- 实现深拷贝还在用JSON.parse(JSON.stringify(obj))?带你用JS实现一个完整版深拷贝函数
使用JavaScript实现深拷贝 1.JSON序列化实现深拷贝 在JS中,想要对某一个对象(引用类型)进行一次简单的深拷贝,可以使用JSON提供给我们的两个方法. JSON.stringfy():可 ...
- CAN总线收发节点设计
CAN总线收发节点设计 写在前面 这是微机接口的一个项目作业. 这段时间一直在宿舍隔离,没办法进行焊接和测试,但原理和代码已经在学习板子上经过验证. 设计目标 CAN在工业现场大量应用,尤其是汽车工业 ...
- vue 项目build后部署上去页面空白
默认情况下vue-cli 会认为项目是部署在域名的根路径上. 但是当项目被部署到了一个子路径上,就要自己选定子路径. 比如项目被部署在了 https://www.ujapp.com/my-app, 则 ...
- python基础练习题(题目 取一个整数a从右端开始的4〜7位。)
day36 --------------------------------------------------------------- 实例054:位取反.位移动 题目 取一个整数a从右端开始的4 ...
- Java中时间类中的Data类与Time类
小简博客 - 小简的技术栈,专注Java及其他计算机技术.互联网技术教程 (ideaopen.cn) Data类 Data类中常用方法 boolean after(Date date) 若当调用此方法 ...
- js实现图片懒加载原理
原理 图片懒加载是前端页面优化的一种方式,在页面中有很多图片的时候,图片加载就需要很多时间,很耗费服务器性能,不仅影响渲染速度还会浪费带宽,为了解决这个问题,提高用户体验,所以就出现了懒加载这种方式来 ...