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的更多相关文章

  1. Noip模拟70 2021.10.6

    T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...

  2. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

  3. 10.17 NOIP模拟赛

    目录 2018.10.17 NOIP模拟赛 A 咒语curse B 神光light(二分 DP) C 迷宫maze(次短路) 考试代码 B 2018.10.17 NOIP模拟赛 时间:1h15min( ...

  4. NOIP模拟赛-2018.11.5

    NOIP模拟赛 好像最近每天都会有模拟赛了.今天从高二逃考试跑到高一机房,然而高一也要考试,这回好像没有拒绝的理由了. 今天的模拟赛好像很有技术含量的感觉. T1:xgy断句. 好诡异的题目,首先给出 ...

  5. 【HHHOJ】NOIP模拟赛 捌 解题报告

    点此进入比赛 得分: \(30+30+70=130\)(弱爆了) 排名: \(Rank\ 22\) \(Rating\):\(-31\) \(T1\):[HHHOJ260]「NOIP模拟赛 捌」Dig ...

  6. NOIP模拟题17.9.26

    B 君的任务(task)[题目描述]与君初相识,犹如故人归.B 君看到了Z 君的第一题,觉得很难.于是自己出了一个简单题.你需要完成n 个任务,第i 任务有2 个属性ai; bi.其中ai 是完成这个 ...

  7. NOIP模拟17.9.22

    NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥

  8. NOIP模拟 17.8.17

    NOIP模拟17.8.17 A 小 G 的字符串文件名 输入文件 输出文件 时间限制 空间限制str.pas/c/cpp str.in str.out 1s 128MB[题目描述]有一天,小 L 给小 ...

  9. NOIP模拟 17.8.16

    NOIP模拟17.8.16 A 债务文件名 输入文件 输出文件 时间限制 空间限制debt.pas/c/cpp debt.in debt.out 1s 128MB[题目描述]小 G 有一群好朋友,他们 ...

  10. NOIP模拟 17.8.14

    NOIP模拟17.8.14 (天宇哥哥考察细心程度的题) [样例解释]如果删去第一个 1:在[3,1,2]中有 3 个不同的数如果删去 3:在[1,1,2]中有 2 个不同的数如果删去第二个 1:在[ ...

随机推荐

  1. 浅谈TypeScript对业务可维护性的影响

    前言 笔者认为, TypeScript是服务于业务的, 核心就是提高代码的可维护性. TypeScript是把双刃剑, 如果类型系统使用的不好, 反而会阻碍开发, 甚至最后就变成了anyScript. ...

  2. Greenplum Jdbc 调用 SETOF refcursor

    最近公司需要用Greenplum,在调用 jdbc的时候遇到了一些问题.由于我们前提的业务都是使用 sqlserver,sqlserver的 procedure 在前端展示做数据源的时候才用的非常多, ...

  3. 《C# in depth》第5章C#5.0中的更改(十二)——指针和非安全编码

    指针类型是一种C# 5.0 中引入的不安全代码特性,它允许程序员直接访问内存地址,以及使用指向变量和对象的指针.指针类型可以帮助程序员处理一些高性能场景,例如在大型数组中查找数据. 指针类型需要使用 ...

  4. 力扣534(MySQL)-游戏玩法分析Ⅲ(中等)

    题目: 需求:请编写一个 SQL 查询,同时报告每组玩家和日期,以及玩家到目前为止玩了多少游戏.也就是说,在此日期之前玩家所玩的游戏总数.详细情况请查看示例. 查询结果格式在以下示例中: 对于 ID ...

  5. EMR重磅发布智能运维诊断系统(EMR Doctor)——开源大数据平台运维利器

    简介: E-MapReduce 推出面向开源大数据集群的智能运维诊断系统 E-MapReduce Doctor,有效提升大数据集群运维效率,辅助 EMR 用户完善集群监控体系. 大数据运维的挑战-如何 ...

  6. MySQL实战—更新过程

    和查询流程不同的是,更新流程涉及两个重要的日志模块:redo log(重做日志)和 binlog(二进制日志). redo log redo log通常是物理日志,记录的是数据页的物理修改,而不是某一 ...

  7. OpenYurt:延伸原生 Kubernetes 到边缘场景下的落地实践

    简介: 随着云原生技术的逐步成熟,阿里云容器服务团队在具体落地实践过程中不断探索云原生技术的应用边界.同时随着物联网和 5G 的迅猛发展,传统的边缘计算架构已经不能满足业务发展的需要. 如何基于云原生 ...

  8. SLS控制台内嵌操作指南

    简介: SLS控制台内嵌操作指南 一.机制 详见:https://help.aliyun.com/document_detail/74971.html 二.操作 2.1 子账号操作(主账号身份操作) ...

  9. 什么是 objdump 命令

    objdump 是在类 Unix 操作系统上显示关于目标文件的各种信息的命令行程序. 它以一种可阅读的格式让你更多地了解二进制文件可能带有的附加信息. 简单来说,和 IDA 这类软件都可用于反汇编. ...

  10. [Go] 浅谈 gorm 执行 AutoMigrate 的两种时机

    第一种就是直接在操作 model 的逻辑中,执行 db.AutoMigrate,模型没有更新时不会有 schema 相关的 sql 被执行. 第二种就是单独定义一个属于 main 包的 go 文件,专 ...