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. React的理解以及特性

    一.是什么 React,用于构建用户界面的 JavaScript 库,提供了 UI 层面的解决方案 遵循组件设计模式.声明式编程范式和函数式编程概念,以使前端应用程序更高效 使用虚拟DOM来有效地操作 ...

  2. 配置服务器SSH PAM防止暴力破解

    正常机器如果开启ssh可能会被暴力破解用户密码,可以配置ssh的pam限制登录失败时可以锁定用户一段时间,就算密码输入正确也无法登录,等恢复之后才可以再次进入,对于不同的发行版配置可能略有不同,对于r ...

  3. C#的窗体假关闭操作例子 - 开源研究系列文章

    晚上编码的时候,想到了以前编写的窗体关闭的事情,就是带托盘图标的应用,有一个主显示操作窗体,但是主窗体点击关闭按钮的时候,实际上是窗体隐藏而非真正关闭,这个在其它的一些应用程序里有这个效果.于是就想到 ...

  4. 力扣33(java&python)-搜索旋转排序数组(中等)

    题目: 整数数组 nums 按升序排列,数组中的值 互不相同 . 在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 ...

  5. 力扣504(java)-七进制数(简单)

    题目: 给定一个整数 num,将其转化为 7 进制,并以字符串形式输出. 示例 1: 输入: num = 100输出: "202"示例 2: 输入: num = -7输出: &qu ...

  6. 国内唯一连续入选Gartner,Quick BI是如何做到的?

    ​简介:阿里云Quick BI凭借灵活的公共云部署,私有化独立部署能力.无缝对接各类云上数据库和自建数据库.可视化搭建分析.高效数据处理能力与强大数据计算能力,使得在2022年持续入选Gartner ...

  7. Flink 在顺丰的应用实践

    ​简介: 顺丰基于 Flink 建设实时数仓的思路,引入 Hudi On Flink 加速数仓宽表,以及实时数仓平台化建设的实践. 本⽂由社区志愿者苗文婷整理,内容源⾃顺丰科技大数据平台研发工程师龙逸 ...

  8. [PHP] 小数转科学计数法, 小数保留 n 位

    使用sprintf / printf 的 %e 或%E 格式说明符将其转换为科学计数法. 使用精度控制符指定保留多少位. 例如:sprintf('%.4e', 0.00000123); Link:ht ...

  9. [Go] 结构体成员的第三个位置上标签的作用

    结构体成员加了第三个位置的标签,在转换指定类型时,key 会使用指定的名字. package main import ( "encoding/json" "log&quo ...

  10. WPF 简单聊聊如何使用 DrawGlyphRun 绘制文本

    在 WPF 里面,提供的使用底层的方法绘制文本是通过 DrawGlyphRun 的方式,此方法适合用在需要对文本进行精细控制的定制化控件上.此方法特别底层而让调用方法比较复杂,本文告诉大家一些简单的使 ...