NOIP模拟70
T1 暴雨
解题思路
\(f_{i,j,k,0/1}\) 表示前 i 个铲平 j 个当前最高的是 k 并且当前是 奇数/偶数 的方案数。
由于只可以铲平 k 块,因此对于同一种 \(i,j\) 而言高度只可能有 k+1 种,这些我们可以用 set 预处理出来。。
然后前后都做一遍 DP 在合并的时候枚举最高高度,同时枚举左右的最大值取值计入答案就好了。
code
#include <bits/stdc++.h>
#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=25e3+10,mod=1e9+7;
int n,m,num[N];long long ans;
struct Node
{
int s[N],f[N][26][30][2],rec[N][30],all[N];
unordered_map<int,int> mp[N];
set<int> se;
void solve()
{
for(int i=0;i<=n;i++)
{
for(auto it=se.begin();it!=se.end();it++)
mp[i].insert(make_pair((*it),++all[i])),rec[i][all[i]]=(*it);
if(mp[i].find(s[i])==mp[i].end()) mp[i].insert(make_pair(s[i],++all[i])),rec[i][all[i]]=s[i];
se.insert(s[i]); if(se.size()>m+1) se.erase(se.begin());
}
f[0][0][1][0]=1;
for(int i=0;i<n;i++)
for(int j=0;j<=m;j++)
for(int k=1;k<=all[i];k++)
for(int pos=0;pos<=1;pos++)
if(f[i][j][k][pos])
{
int val=max(s[i+1],rec[i][k]),p=pos^(val-s[i+1])&1;
int id=mp[i+1].find(val)->second;
f[i+1][j][id][p]=(f[i+1][j][id][p]+f[i][j][k][pos])%mod;
if(j>=m) continue;
val=rec[i][k]; id=mp[i+1].find(val)->second; p=pos^(val&1);
f[i+1][j+1][id][p]=1ll*(1ll*f[i+1][j+1][id][p]+1ll*f[i][j][k][pos])%mod;
}
}
}pre,suf;
signed main()
{
freopen("rain.in","r",stdin); freopen("rain.out","w",stdout);
n=read(); m=read();
for(int i=1;i<=n;i++) pre.s[i]=num[i]=read(),suf.s[n-i+1]=num[i];
pre.solve(); suf.solve();
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
for(int k=1;k<=pre.all[i];k++)
if(pre.rec[i-1][k]<num[i])
for(int pos=0;pos<=1;pos++)
if(pre.f[i-1][j][k][pos])
for(int q=1;q<=suf.all[n-i];q++)
if(suf.rec[n-i][q]<=num[i])
ans=(ans+1ll*pre.f[i-1][j][k][pos]*suf.f[n-i][m-j][q][pos])%mod;
printf("%lld",ans);
return 0;
}
T2 AVL 树
解题思路
首先对于整棵树我们可以初始化出来对于不同深度的树至少有多少节点。
然后对于子树进行搜索优先搜左子树,每次跳父亲看是否可以加入,由于这是一颗 AVL 树,因此树高接近 \(log\) 。
于是我们就可以对于父亲节点来更新自己的限制,并且根据左子树来更新右子树的限制。
code
#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
#define ls son[x][0]
#define rs son[x][1]
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=5e5+10;
int n,m,root,mxdep[N],dep[N],use[N],lim[N],g[50],fa[N],son[N][2];
bool vis[N];
void dfs(int x)
{
dep[x]=dep[fa[x]]+1; mxdep[x]=dep[x];
if(ls) dfs(ls),mxdep[x]=max(mxdep[x],mxdep[ls]);
if(rs) dfs(rs),mxdep[x]=max(mxdep[x],mxdep[rs]);
}
bool judge(int x)
{
int temp=max(dep[x],use[x]),cnt=0;
while(x)
{
cnt+=vis[x]^1; temp=max(temp,use[x]);
if(x==son[fa[x]][0]&&son[fa[x]][1])
cnt+=g[max(temp-1,lim[son[fa[x]][1]])-dep[fa[x]]];
x=fa[x];
}
return cnt<=m;
}
void insert(int x)
{
int temp=use[x]=max(use[x],dep[x]);
while(x)
{
m-=vis[x]^1; vis[x]=true; use[x]=max(use[x],temp);
if(x==son[fa[x]][0]&&son[fa[x]][1]&&!vis[son[fa[x]][1]])
lim[son[fa[x]][1]]=max(lim[son[fa[x]][1]],use[x]-1);
x=fa[x];
}
}
void work(int x)
{
int tmp1=ls,tmp2=rs; if(mxdep[ls]>=lim[x]) swap(tmp1,tmp2);
lim[tmp1]=max(lim[tmp1],lim[x]-1); lim[tmp2]=max(lim[tmp2],lim[x]);
}
void solve(int x)
{
if(judge(x)) insert(x);
if(ls&&rs) work(x);
else if(ls) lim[ls]=max(lim[ls],lim[x]);
else if(rs) lim[rs]=max(lim[rs],lim[x]);
if(ls) solve(ls); if(rs) solve(rs);
}
signed main()
{
freopen("avl.in","r",stdin); freopen("avl.out","w",stdout);
n=read(); m=read();
g[1]=1; for(int i=2;i<=40;i++) g[i]=g[i-1]+g[i-2]+1;
for(int i=1;i<=n;i++)
{
fa[i]=read();
if(~fa[i]&&fa[i]<i) son[fa[i]][1]=i;
else if(~fa[i]&&fa[i]>i) son[fa[i]][0]=i;
else root=i;
}
fa[root]=0; dfs(root); solve(root);
for(int i=1;i<=n;i++) printf("%lld",(int)vis[i]);
return 0;
}
T3 挖掘机
解题思路
比较暴力的一个思路就是对于每一个点求出它只操作一次可以到达的最远位置,然后依次跳链表。
这个东西是可以倍增优化的,每次跳 \(2^i\) 步,代码实现也不太难。。
只可惜我一直以为是线段树维护。。
code
#include <bits/stdc++.h>
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;
int n,m,q,len,nxt[13][N],f[13][N][18];
char s[13][N];
void solve()
{
int dep,l,r,ans=0; dep=read(); l=read(); r=read();
for(int i=1;i<=dep;i++)
{
int pos=l;
if(s[i][pos]=='.') pos=nxt[i][pos]+1;
for(int j=17;j>=0&&pos<=r;j--)
if(f[i][pos][j]&&f[i][pos][j]<=r)
ans+=1ll<<j,pos=f[i][pos][j];
if(s[i][pos]=='.') pos=nxt[i][pos]+1;
if(pos<=r) ans++;
}
printf("%d\n",ans);
}
void Init_Work(int pos)
{
for(int i=m;i>=1;i--)
{
if(s[pos][i]=='X') f[pos][i][0]=i+len;
else f[pos][i][0]=nxt[pos][i]+len+1;
for(int j=0;f[pos][i][j];j++)
f[pos][i][j+1]=f[pos][f[pos][i][j]][j];
}
}
signed main()
{
freopen("blueshit.in","r",stdin); freopen("blueshit.out","w",stdout);
n=read(); m=read(); len=read(); q=read();
for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
for(int i=1;i<=n;i++)
for(int j=m,las;j>=1;j--)
{
if(s[i][j]!=s[i][j+1]) las=j;
nxt[i][j]=las;
}
for(int i=1;i<=n;i++) Init_Work(i);
while(q--) solve();
return 0;
}
T4 游戏
大坑未补
NOIP模拟70的更多相关文章
- Noip模拟70 2021.10.6
T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
- 10.17 NOIP模拟赛
目录 2018.10.17 NOIP模拟赛 A 咒语curse B 神光light(二分 DP) C 迷宫maze(次短路) 考试代码 B 2018.10.17 NOIP模拟赛 时间:1h15min( ...
- NOIP模拟赛-2018.11.5
NOIP模拟赛 好像最近每天都会有模拟赛了.今天从高二逃考试跑到高一机房,然而高一也要考试,这回好像没有拒绝的理由了. 今天的模拟赛好像很有技术含量的感觉. T1:xgy断句. 好诡异的题目,首先给出 ...
- 【HHHOJ】NOIP模拟赛 捌 解题报告
点此进入比赛 得分: \(30+30+70=130\)(弱爆了) 排名: \(Rank\ 22\) \(Rating\):\(-31\) \(T1\):[HHHOJ260]「NOIP模拟赛 捌」Dig ...
- NOIP模拟题17.9.26
B 君的任务(task)[题目描述]与君初相识,犹如故人归.B 君看到了Z 君的第一题,觉得很难.于是自己出了一个简单题.你需要完成n 个任务,第i 任务有2 个属性ai; bi.其中ai 是完成这个 ...
- NOIP模拟17.9.22
NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥
- NOIP模拟 17.8.17
NOIP模拟17.8.17 A 小 G 的字符串文件名 输入文件 输出文件 时间限制 空间限制str.pas/c/cpp str.in str.out 1s 128MB[题目描述]有一天,小 L 给小 ...
- NOIP模拟 17.8.16
NOIP模拟17.8.16 A 债务文件名 输入文件 输出文件 时间限制 空间限制debt.pas/c/cpp debt.in debt.out 1s 128MB[题目描述]小 G 有一群好朋友,他们 ...
- NOIP模拟 17.8.14
NOIP模拟17.8.14 (天宇哥哥考察细心程度的题) [样例解释]如果删去第一个 1:在[3,1,2]中有 3 个不同的数如果删去 3:在[1,1,2]中有 2 个不同的数如果删去第二个 1:在[ ...
随机推荐
- Caused by: org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration$ArtifactResolveException: Could not resolve all files for configuration ':classpath'.
前言 这个错误怎么看呢? 如果你对gradle 不是很了解的话,有一个建议,就是把异常背下来,当然是看这个:ArtifactResolveException哈. 而不是后面的详情. 正文 给我们详情是 ...
- Vue3 解构赋值失去响应式引发的思考
前言 vue3发布以来经历两年风头正盛,现在大有和react 平分秋色的势头,我们知道他是基于proxy 实现响应式的能力, 解决了vue2所遗留下来的一些问题,同时也正由于proxy的特性,也提高了 ...
- 【笔记】go语言--Map
go语言--Map //基本结构,定义 m := map[string] string { "name" : "ccmouse",//这些是无序的,是hashm ...
- SVN Windows10的安装
SVN Windows安装与配置 先去到官网的下载链接:Download Apache Subversion Sources 然后点这个 binary packages 在这里能看到大多数的操作系统的 ...
- 力扣26(java&python)-删除有序数组中的重复项(简单)
题目: 给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度.元素的 相对顺序 应该保持 一致 . 由于在某些语言中不能改变数组的长 ...
- dotnet 在国产 UOS 系统利用 dotnet tool 工具做文件传输
我在一台设备上安装了 UOS 系统,但是我如何在我的主开发设备上和 UOS 系统传输文件?通过 dotnet tool 工具可以完成大部分的工作,当然,使用 dotnet tool 不仅做文件传输,还 ...
- Sentinel如何持久化数据到Nacos?
默认情况下 Sentinel 只能接收到 Nacos 推送的消息,但不能将自己控制台修改的信息同步给 Nacos,如下图所示: 但是在生成环境下,我们为了更方便的操作,是需要将 Sentinel 控制 ...
- Ubuntu环境下docker每次都需要sudo的问题
1.添加 docker 用户组 sudo groupadd docker 可以通过 cat /etc/group 指令查看存在的用户组 2.将当前用户添加到 docker 组中 sudo gpassw ...
- 史上功能最全的Java权限认证框架!
大家好,我是 Java 陈序员.权限认证是我们日常开发绕不过的话题,这是因为我们的应用程序需要防护,防止被窜入和攻击. 在 Java 后端开发中,实现权限认证有很多种方案可以选择,一个拦截器.过滤器也 ...
- Java IO流文件
Java IO流文件 创建文件 使用File类进行创建文件操作,创建该对象包含三种构造方法 new File(String pathname); //根据路径+文件名创建一个File对象 new Fi ...