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& ...
随机推荐
- 错误 内存溢出 vendor/composer/autoload_real.php on line 66
前言 首先声明我没怎么写过php,只是当时室友做php的时候跟他一起学了几分钟. 有时候部署一些php项目的时候,发生一些错误,但是百度一下五花八门的. 这个错误的完整版是: Fatal error: ...
- 百度AIPNLP 文本相似度 文本审核
效果不如有监督的bert文本相似度好 from aip import AipNlp APP_ID = "22216281" APT_KEY = "foEeYauuvnqW ...
- Kafka 集群副本数量调整
Kafka 创建时未指定多个副本或者副本数量过少,都可以在后期手动添加,另外如果副本过多也可以减少,当前调整基于 Kafka 的版本是 2.5.1,但是估计 2.1 ~ 2.5 应该都是兼容的. 下面 ...
- 记录如何用php做一个网站访问计数器的方法
简介创建一个简单的网站访问计数器涉及到几个步骤,包括创建一个用于存储访问次数的文件或数据库表,以及编写PHP脚本来增加计数和显示当前的访问次数. 方法以下是使用文件存储访问次数的基本步骤: 创建一个文 ...
- 使用GitHub Actions和GitHub pages实现前端项目的自动打包部署
1. 引言 As we all know,前端部署项目是比较简单的,通常情况下只需要将打包的产物(index.html..js文件..css文件等)放在Web服务器下就,这种叫静态资源托管,成本是比较 ...
- 力扣423(java)-从英文中重建数字(中等)
题目: 给你一个字符串 s ,其中包含字母顺序打乱的用英文单词表示的若干数字(0-9).按 升序 返回原始的数字. 示例 1: 输入:s = "owoztneoer"输出:&quo ...
- 转载 | 如何把 thinkphp5 的项目迁移到阿里云函数计算来应对流量洪峰?
简介: 函数计算评测局的优秀征文! 如何把thinkphp5的项目迁移到阿里云函数计算来应对流量洪峰? 1. 为什么要迁移到阿里云函数? 我的项目是一个节日礼品领取项目,过节的时候会有短时间的流量洪峰 ...
- 【实践案例】Databricks 数据洞察在美的暖通与楼宇的应用实践
简介: 获取更详细的 Databricks 数据洞察相关信息,可至产品详情页查看:https://www.aliyun.com/product/bigdata/spark 作者 美的暖通与楼宇事业部 ...
- AI圈内卷?天池团聚请来专家集体“问诊”
简介: 近期杭州云栖大会上出现了一个"数据博物馆",最吸引眼球的"展品",竟是行业大规模开源数据集.不仅数量多达上百个,还覆盖零售.文娱.工业.医疗.自然科学 ...
- [FAQ] 对于 Puppeteer 和 Chromium 在 Linux 上的安装,需要安装哪些依赖库
比如 puppeteer/chrome/linux-114.0.5735.133/chrome-linux64/chrome 到底要装哪些依赖. 一般根据报错提示,安装缺少的即可,以下是一般需要的 ...