noip模拟43
A. 第一题
儿子遍历顺序按深度由小到大即可
B. 第二题
二分最小值,以点权作为初始距离跑最长路即可
直接用大根堆跑 \(dij\) 会 \(T\),考虑初始权值可以处理,且边权一定,用类似蚯蚓的方法开两个队列,一开始都在第一个队列,松弛后的点放第二个,容易发现两个队列都是单调递减的,比较队头即可
也可以直接 \(spfa\) 到不能松弛为止,由于图的特殊性不会更新很多次
代码实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e7+5;
const int maxm=5e7+5;
int n,m,k,val[maxn],dis[maxn],hd[maxn],cnt;
bool vis[maxn];
int movx[10]={0,0,-1,-1,1,1};
int movy[10]={-1,1,0,1,-1,0};
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
struct Edge{
int nxt,to;
}edge[maxm];
void add(int u,int v){
edge[++cnt].nxt=hd[u];
edge[cnt].to=v;
hd[u]=cnt;
return ;
}
struct Node{
int dis,id;
Node(){}
Node(int x,int y):dis(x),id(y){}
bool operator < (const Node &x)const{
return dis>x.dis;
}
}p[maxn];
queue<int>q1,q2;
bool check(int limit){
for(int i=1;i<=n*m;i++){
dis[p[i].id]=p[i].dis;
q1.push(p[i].id);
}
memset(vis,0,sizeof vis);
while((!q1.empty())||(!q2.empty())){
int x=0,y=0,u=0;
if(!q1.empty())x=q1.front();
if(!q2.empty())y=q2.front();
if(dis[x]>dis[y]){
q1.pop();
u=x;
}
else q2.pop(),u=y;
//cout<<"hhh "<<u<<" "<<dis[u]<<endl;
if(vis[u])continue;
vis[u]=true;
for(int i=hd[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(dis[v]<dis[u]-limit){
dis[v]=dis[u]-limit;
//if(!vis[v])
q2.push(v);
//,vis[v]=true;
}
}
}
int sum=0;
for(int i=1;i<=n*m;i++){
sum+=dis[p[i].id]-p[i].dis;
if(sum>k)return false;
}
return true;
}
bool pd(int x,int y){
return x>=1&&x<=n&&y>=1&&y<=m;
}
int id(int x,int y){
return (x-1)*m+y;
}
signed main(){
// freopen("s.out","r",stdin);
// freopen("my.out","w",stdout);
n=read();
m=read();
k=read();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
val[id(i,j)]=read();
for(int l=0;l<6;l++){
int x=i+movx[l];
int y=j+movy[l];
if(pd(x,y))add(id(i,j),id(x,y));
}
}
}
for(int i=1;i<=n*m;i++){
p[i].dis=val[i];
p[i].id=i;
}
sort(p+1,p+n*m+1);
dis[0]=-1;
// for(int i=1;i<=n*m;i++)cout<<p[i].dis<<" "<<p[i].id<<endl;;
int l=0,r=1000000000000;
while(l<r){
int mid=(l+r)/2;
if(check(mid))r=mid;
else l=mid+1;
}
cout<<l;
return 0;
}
C. 第三题
\(1\) 的个数从大到小依次考虑即可,用数位 \(dp\) 计算个数和总和
这道题是同时卡上下边界的数位 \(dp\)
D. 第四题
设 \(f[i][j]\) 表示前 \(i\) 个数,最大值为 \(j\) 的方案数,转移 \(f[i][j]=f[i-1][j]*j+f[i-1][j-1]\)
设 \(g[i][j]\) 表示从第 \(i\) 个数开始到结尾,开头初始最大值为 \(j\) 的方案数,转移 \(g[i][j]=g[i+1][j]*j+g[i+1][j+1]\)
观察答案形式,由于 \(\displaystyle x^2=\binom{x}{2}*2+1\)
那么强制一个数在数列里出现两次
数 \(j\) 在 \(i\) 位置第一次出现的贡献为:
\]
即讨论上一个数的大小即可
然后用前缀和优化为 \(n^2\)
代码实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=3005;
int n,mod,f[maxn][maxn],g[maxn][maxn],ans,sum2[maxn],sum1[maxn][maxn],sum[maxn][maxn];
signed main(){
cin>>n>>mod;
f[0][0]=1;
// for(int i=0;i<=n;i++)f[0][i]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
f[i][j]=(f[i-1][j-1]+f[i-1][j]*j%mod)%mod;
// cout<<f[i][j]<<" ";
}
}
// g[n+1][n]=g[n+1][n]=1;
for(int i=1;i<=n;i++)g[n+1][i]=1;
for(int i=n;i>=1;i--){
for(int j=n;j>=1;j--){
g[i][j]=(g[i+1][min(j+1,n)]+g[i+1][j]*j%mod)%mod;
}
}
// cout<<g[5][5]<<endl;
for(int i=1;i<=n;i++){
for(int j=n;j>=1;j--){
sum[i][j]=(sum[i][j+1]+f[i-1][j]*g[i+1][j]%mod)%mod;
sum1[i][j]=(sum1[i][j+1]+g[i+2][j]*f[i-1][j]%mod)%mod;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
ans=0;
ans=(sum[i][j]+2*(n-i)%mod*sum1[i][j]%mod)%mod;
// for(int k=j;k<=n;k++){
// ans=(ans+f[i-1][k]*(g[i+1][k]+2*(n-i)%mod*g[i+2][k]%mod)%mod)%mod;
// }
ans=(ans+f[i-1][j-1]*(g[i+1][j]+2*(n-i)%mod*g[i+2][j]%mod)%mod)%mod;
sum2[j]=(sum2[j]+ans)%mod;
}
}
for(int i=1;i<=n;i++)cout<<sum2[i]<<" ";
return 0;
}
noip模拟43的更多相关文章
- 8.18考试总结[NOIP模拟43]
又挂了$80$ 好气哦,但要保持优雅.(草 T1 地衣体 小小的贪心:每次肯定从深度较小的点向深度较大的点转移更优. 模拟一下,把边按链接点的子树最大深度排序,发现实际上只有上一个遍历到的点是对当前考 ...
- Noip模拟43 2021.8.18
T1 地一体 可以树形$dp$,但考场没写出来,只打了没正确性的贪心水了$30$ 然后讲题的时候B哥讲了如何正确的贪心,喜出望外的学习了一下 不难发现 每次士兵都会直接冲到叶子节点 从深的点再返回到另 ...
- [考试总结]noip模拟43
这个题目出的还是很偷懒.... 第一题...第二题...第三题...四.... 好吧... 这几次考得都有些问题,似乎可能是有些疲惫,脑袋也是转不太动,考完总觉得自己是能力的问题,但是改一分钟之后会发 ...
- NOIP模拟 1
NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. # 用 户 名 ...
- NOIP模拟17.9.22
NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥
- NOIP 模拟4 T2
本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...
- noip模拟32[好数学啊]
noip模拟32 solutions 真是无语子,又没上100,无奈死了 虽然我每次都觉得题很难,但是还是有好多上100的 战神都200多了,好生气啊啊啊 从题开始变难之后,我的时间分配越来越不均匀, ...
- 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 ...
随机推荐
- JSP的执行原理、JSP的内置对象、四大作用域解析、MVC模式理解>从零开始学JAVA系列
目录 JSP的执行原理.JSP的内置对象.四大作用域解析.MVC模式理解 JSP的执行原理 这里拿一个小例子来解析JSP是如何被访问到的 首先将该项目部署到tomcat,并且通过tomcat启动 通过 ...
- oracle控制用户权限命令
ORACLE控制用户权限: 首先使用系统中的拥有DBA权限的账号(system)登录: 一.创建用户: 1.DBA使用creater user语句创建用户: --创建登录用户名为:user01,密码为 ...
- Feign实战技巧篇
介绍Feign在项目中的正确打开方式 看了上一期Feign远程调用的小伙伴可能会问:阿鉴,你不是说上一期讲的是Feign的99%常用方式吗?怎么今天还有正确打开方式一说呀? 阿鉴:是99%的常用方式, ...
- 5.1 剑指 Offer 03. 数组中重复的数字
类型题:剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字.在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了, ...
- 模拟退火 Simulated annealing
模拟退火 Simulated annealing 看看有空把图片完善一下好了 模拟退火算法的一些背景 既然要说模拟退火算法,就应该说一下模拟退火算法的背景,模拟退火算法是局部搜索算法的一种扩展,该算法 ...
- JVM钩子函数的使用
一.问题引入 背景 在编写一个需要持续在后台运行的程序的时候遇到了这样的场景:我的程序在主函数中创建了一个线程池周期性地执行任务,我希望主线程和线程池都持续运行,但如果收到外部的关闭信号时,主线程和线 ...
- luogu P4206 聪聪和可可
聪聪和可可 鸽了两天 \(dijkstra\)预处理出来两点之间的最短路径\(dis\)数组,读题发现,\(cat\)的走位很怪sb斩了,所以我们设一个\(next\)数组,\(next[i][j]\ ...
- mybatis面试题总结
1.什么是MyBatis? 答:MyBatis是一个可以自定义SQL.存储过程和高级映射的持久层框架. 2.讲下MyBatis的缓存 答:MyBatis的缓存分为一级缓存和二级缓存,一级缓存放在ses ...
- freecodecamp挑战
freecodecamp挑战 2020年3月21初次挑战 完成45关挑战 2020年3月22日 完成至101关 2020年3月23日 完成至144关 2020年3月24日 完成至187关 css结束 ...
- 【C#】 Stopwatch详解
Stopwatch的命名空间是using System.Diagnostics; 1 namespace System.Diagnostics 2 { 3 // 4 // 摘要: 5 // 提供一组方 ...