NOIP模拟49
虚伪的眼泪,会伤害别人,虚伪的笑容,会伤害自己。
前言
暑假集训过后的第一次考试,成绩一般,没啥好说的
T1 Reverse
解题思路
看到这个题的第一眼就感觉是最短路,毕竟题目的样子就好像之前做过的星空的部分。
然后就是在不到十分钟之后机房就充满了敲键盘的声音。
然后就有了几乎是签到的 57pts ,至于思路嘛,只能说是显然。
考完之后有小常数强者直接 \(\mathcal{O(nk)}\) 切掉。
我看了看我在本机上最大的 \(10^5\) 的样例只跑了 \(0.009s\) 的程序,又试了一边考场上造出来的最大数据 \(10s\) 。
一个邪恶的念头在我内心产生了,把 Dijkstra 改成 SPFA ,再配上一个手写队列,最最重要的是一个 卡时 ,于是我们愉快地切掉此题(成功压进 20 行)。

后来又卡了一下,发现好像可以把卡时的东西稍微开大一点,但是手写队列确实是需要。。
还是稍微写一下正解吧,复杂度是 \(\mathcal{O(nlogn)}\),但是链表实现可以达到 \(\mathcal{O(n)}\) 。
我们当然是学习比较快的打法了。。
其实比较简单,发现对于同一个位置的 1 翻转可以到达的位置只可能是奇数或者偶数的一种。
然后可以卡一下范围,类似于翻转的串的左右端点一定在 \([1,n]\) 。
接下来就是可以通过加减操作得到可以到达的区间内的第一个以及最末尾的数字,从链表跳就好了。
对于更新的区间内的链表值于当前区间右端点取 \(\max\) 这样就可以达到每个点只被扫一边的目的了。
code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=1e5+10,INF=1e9;
int n,pos,m,len,dis[N],nxt[N];
struct Queue
{
int l,r,num[N];
void push(int x){num[++r]=x;}
void pop(){l++;}
int front(){return num[l];}
bool empty(){return l>r;}
}q;
signed main()
{
n=read(); len=read(); m=read(); pos=read();
memset(dis,0x3f,sizeof(dis)); dis[pos]=0; q.push(pos);
for(int i=1,x;i<=m;i++) x=read(),dis[x]=-1;
for(int i=1;i<=n;i++) nxt[i]=i+2;
while(!q.empty())
{
int x=q.front(); q.pop();
int fro=2*max(1ll,x-len+1)+len-x-1,to=2*min(n-len+1,x)+len-x-1;
for(int i=fro;i<=to;i=nxt[i]) if(dis[i]>dis[x]+1) dis[i]=dis[x]+1,q.push(i);
for(int i=fro,pre=nxt[i];i<=to;i=pre,pre=nxt[i]) nxt[i]=max(nxt[i],to);
}
for(int i=1;i<=n;i++) printf("%lld ",dis[i]>=INF?-1:dis[i]);
return 0;
}
T2 Silhouette
解题思路
二项式反演
不难发现两个数组的顺序对于答案是没有影响的,因此我们可以将它们从大到小进行排序。
那么我们就可以发现,对于所有 \(S=\min(A_i,b_j)\) 相同的位置,从大到小进行枚举。
我们每次所要求的值的范围就变成了一个矩形或者一个 L 形。
先说一下矩形的操作,设 \(f(i)\) 表示至少有 i 行不满足条件的方案数,前提是所有的列都符合条件,假设当前计算的是一个 \(a\times b\) 的矩形,那么根据二项式反演,答案就是 \(\sum\limits_{i=0}^a(-1)^i\times f(i)\)。
\]
同样的假设我们现在求的 L 形是一个 \(A\times B\) 挖去一个 \((A-a)\times(B-b)\) 的形状,我们可以把 L 形看作为两个矩形,也就可以得出下面的柿子:
\]
code
#include<bits/stdc++.h>
#define int long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=1e5+10,mod=1e9+7;
int n,ans=1,pos1=1,pos2=1,fac[N],inv[N],fro[N],nex[N];
int power(int x,int y)
{
int temp=1; x%=mod; y%=(mod-1);
while(y)
{
if(y&1) temp=temp*x%mod;
x=x*x%mod; y>>=1;
}
return temp;
}
void init()
{
fac[0]=inv[0]=1; for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
inv[n]=power(fac[n],mod-2); for(int i=n-1;i>=1;i--) inv[i]=inv[i+1]*(i+1)%mod;
}
int C(int x,int y){return fac[x]*inv[y]%mod*inv[x-y]%mod;}
signed main()
{
n=read(); init();
for(int i=1;i<=n;i++) fro[i]=read(); sort(fro+1,fro+n+1); reverse(fro+1,fro+n+1);
for(int i=1;i<=n;i++) nex[i]=read(); sort(nex+1,nex+n+1); reverse(nex+1,nex+n+1);
while(pos1<=n||pos2<=n)
{
int tot=0,temp=max(fro[pos1],nex[pos2]),cnt1,cnt2,pre1=pos1,pre2=pos2;
while(pos1<=n&&fro[pos1]==temp) pos1++; cnt1=pos1-pre1;
while(pos2<=n&&nex[pos2]==temp) pos2++; cnt2=pos2-pre2;
for(int i=0,base=1;i<=cnt1;i++,base*=-1) tot=(tot+base*C(cnt1,i)*power(power(temp,i)*(power(temp+1,pos1-i-1)-power(temp,pos1-i-1)+mod),cnt2)%mod*power(power(temp,i)*power(temp+1,cnt1-i),pos2-cnt2-1)%mod+mod)%mod;
ans=ans*tot%mod;
}
printf("%lld",ans);
return 0;
}
T3 Seat
解题思路
好像并不是特别可做,于是果断去颓 skyh 学长的 blog 了。。
DP 数组的含义和题解上一样 \(f_{i,j}\) 表示已经坐下了 \(i\) 个人,还剩下 \(j\) 个长度为偶数区间的区间的概率。
首先处理出一组可行的解来,也就是代码里 20 到 31 行所做的事情。
然后枚举区间长度,对于每一种存在的区间长度,枚举所剩下的人,以及所剩下的长度为偶数的区间。
对于这一次选择的是奇数或者偶数的区间分别进行转移,注意这里的偶数的区间有两个位置可供选择。
然后再对于偶数区间进行一些特殊处理,然后这个题解就愉快地水过去了;
code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=1e3+50,M=3e4+10;
int n,mod,sum,pos[N],tot[N],odd[N],f[N][N],g[N][N],ans[N][N],inv[M];
bool vis[N];
signed main()
{
sum=n=read(); mod=read(); inv[1]=1; vis[0]=vis[n+1]=true;
for(int i=2;i<mod;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
for(int i=1;i<=n;i++)
{
int l=0,r=0,mx;
for(int j=0,id=1;j<=n;j++,id=j+1)
{
while(!vis[id]) id++;
if(id-j>r-l) l=j,r=id;
j=id-1;
}
mx=(r-l)>>1; tot[mx]++; odd[mx]+=!((r-l-1)&1);
pos[i]=l+mx; vis[pos[i]]=true;
}
for(int i=sum-tot[1]+1;i<=sum;i++)
for(int j=sum-tot[1]+1;j<=sum;j++)
ans[i][pos[j]]=inv[tot[1]];
sum-=tot[1];
for(int i=2;i<=n;i++)
if(tot[i])
{
int fro=sum-tot[i]+1,to=sum,id=fro+odd[i]-1;
for(int j=0;j<=tot[i];j++) fill(f[j]+0,f[j]+odd[i]+1,0); f[0][odd[i]]=1;
for(int j=1,ow=0,ew=0;j<=tot[i];j++,ow=0,ew=0)
{
for(int k=0;k<=odd[i];k++)
if(f[j-1][k])
{
int res=(tot[i]-j+1)+k,temp;
if(k)
{
temp=f[j-1][k]*k%mod*2*inv[res]%mod;
(ow+=temp*inv[odd[i]*2])%mod;
f[j][k-1]=(f[j][k-1]+temp)%mod;
}
if(tot[i]-odd[i])
{
temp=f[j-1][k]*(res-2*k+mod)%mod*inv[res]%mod;
(ew+=temp*inv[tot[i]-odd[i]])%=mod;
f[j][k]=(f[j][k]+temp)%mod;
}
}
for(int k=fro;k<=id;k++)
ans[fro+j-1][pos[k]]=(ans[fro+j-1][pos[k]]+ow)%mod,
ans[fro+j-1][pos[k]+1]=(ans[fro+j-1][pos[k]+1]+ow)%mod;
for(int k=id+1;k<=to;k++) ans[fro+j-1][pos[k]]=(ans[fro+j-1][pos[k]]+ew)%mod;
}
for(int j=fro;j<=id;j++)
{
int l=pos[j]-i+1,r=pos[j]+i;
for(int p=l;p<=r;p++)
if(p!=pos[j])
for(int q=to+1,temp=(p<pos[j])?p+i+1:p-i,val=ans[q][p]*inv[2]%mod;q<=n;q++,temp=(p<pos[j])?p+i+1:p-i,val=ans[q][p]*inv[2]%mod)
g[q][p]=(g[q][p]+val)%mod,g[q][temp]=(g[q][temp]+val)%mod;
for(int p=l;p<=r;p++)
for(int q=to+1;q<=n;q++)
ans[q][p]=g[q][p],g[q][p]=0;
}
sum-=tot[i];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++) printf("%lld ",ans[i][j]);
printf("\n");
}
return 0;
}
NOIP模拟49的更多相关文章
- Noip模拟49 2021.9.7
T1 reverse 又一道板子打假的挂分题,直接挂到倒二.. 考场上思路神奇,居然想到用$bfs$建边然后跑最短路, 其实当时也想到了直接$bfs$,但是不知道为啥觉得$dij$屌就没直接打$bfs ...
- 2021.9.7考试总结[NOIP模拟49]
T1 Reverse $BFS$暴力$O(n^2)$ 过程中重复枚举了很多点,考虑用链表记录当前点后面可到达的第一个未更新点. 搜索时枚举翻转子串的左端点,之后便可以算出翻转后$1$的位置. $cod ...
- CH Round #49 - Streaming #4 (NOIP模拟赛Day2)
A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...
- NOIP模拟 1
NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. # 用 户 名 ...
- NOIP模拟17.9.22
NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥
- 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组
2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...
- NOIP 模拟4 T2
本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...
- 2021.9.17考试总结[NOIP模拟55]
有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
随机推荐
- redis 简单整理——持久化之AOF[二十]
前言 简单介绍一下AOF. 正文 AOF(append only file)持久化:以独立日志的方式记录每次写命令, 重启时再重新执行AOF文件中的命令达到恢复数据的目的. AOF的主要作用 是解决了 ...
- c++ 中const 原理
前言 在c++ 中和别的语言不一样,高级语言是将const编译了,c又不同这里不介绍,而c++ 是实现了. 正文 const 原理 请看一个解析: const a=10; int*p=&a; ...
- 使用 Docker 部署 instantbox 轻量级 Linux 系统
1)instantbox 介绍 GitHub:https://github.com/instantbox/instantbox instantbox 是一款非常实用的项目,它能够让你在几秒内启动一个主 ...
- log4j2 lookup漏洞修复方法
2021.12.10凌晨,Apache Log4j远程代码执行漏洞细节被公开,参考链接:https://unit42.paloaltonetworks.com/apache-log4j-vulnera ...
- HarmonyOS NEXT应用开发之图片缩放效果实现
介绍 图片预览在应用开发中是一种常见场景,在诸如QQ.微信.微博等应用中均被广泛使用.本模块基于Image组件实现了简单的图片预览功能. 使用说明: 双指捏合缩放图片大小 双击图片进行图片的大小切换 ...
- PolarDB-X 2.0:使用一个透明的分布式数据库是一种什么体验
简介: 透明分布式,是PolarDB-X即将发布的能力,它能让应用在使用PolarDB-X的过程中,犹如使用单机数据库一般的体验.与传统的中间件类型的"分布式数据库"相比,有了透明 ...
- Apache Dubbo 3.0.0 正式发布 - 全面拥抱云原生
简介: 一个新的里程碑! 一.背景 自从 Apache Dubbo 在 2011 年开源以来,在一众大规模互联网.IT公司的实践中积累了大量经验后,Dubbo 凭借对 Java 用户友好.功能丰富.治 ...
- [FE] iframe 相关选项 x-frame-options: 设置 meta 标签无效 & helmet
The X-Frame-Options HTTP 响应头是用来给浏览器 指示允许一个页面 可否在 <frame>, <iframe>, <embed> 或者 < ...
- [TP5] 浅谈 ThinkPHP 的 Hook 行为事件及监听执行
TP5 中使用 \think\Hook::add('xx', '\app\xxx\behavior\Xx') 注册行为. 也可以在 application/tags.php 中统一注册. 在需要监听执 ...
- 4.prometheus监控--监控linux服务器
一.监控linux服务器 1.1 二进制安装 # 客户端操作wget https://github.com/prometheus/node_exporter/releases/download/v1. ...