[ZROI 9.16模拟赛] Tutorial
Link:
A:
套路题结果想了好久……
排序二叉树的性质就是中序遍历单调递增
于是只考虑当前树的中序遍历的序列即可,与树的形态无关
将序列改成严格单调增想到最大化不变的数,但直接LIS求的是改为非严格单调增的数
一个将严格单调增问题改为非严格的套路是将数$a_i$替换成$a_i-i$,对转换后序列求LIS即可
(其实也可以理解为在严格单增问题中能拓展的条件为$a[i]-a[k]\ge i-k$,那么也就是$a[i]-i\ge a[k]-k$)
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
#define pb push_back
typedef double db;
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=2e5+;
ll dat[MAXN],ind[MAXN],tot;
int n,x,y,ch[MAXN][],dp[MAXN],res; void dfs(int x)
{
if(~ch[x][]) dfs(ch[x][]);
ind[++tot]=dat[x];
if(~ch[x][]) dfs(ch[x][]);
} int main()
{
scanf("%d",&n);
memset(ch,-,sizeof(ch));
for(int i=;i<=n;i++)
scanf("%lld",&dat[i]);
for(int i=;i<n;i++)
scanf("%d%d",&x,&y),ch[x][y]=i+;
dfs();dp[]=-<<; for(int i=;i<=n;i++) ind[i]-=i;
for(int i=;i<=n;i++)
{
if(ind[i]>=dp[res]) dp[++res]=ind[i];
else dp[upper_bound(dp+,dp+res+,ind[i])-dp]=ind[i];
}
printf("%d",n-res);
return ;
}
Problem A
B:
长度可行性单调,对长度二分答案
发现区间$[l,r]$中存在$k$的条件为:$gcd(l...r)=min(l...r)=k$
区间最小和$gcd$明显可以用$RMQ$维护,但此题卡$log^2$,因此只能用$ST$表来维护
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
#define pb push_back
typedef double db;
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=5e5+;
int res[MAXN],tot;
int n,dat[MAXN],lg2[MAXN],mn[MAXN][],gcd[MAXN][];
int GCD(int x,int y){return x%y==?y:GCD(y,x%y);} void pre()
{
lg2[]=;
for(int i=;i<=n;i++)
lg2[i]=lg2[i-]+((<<(lg2[i-]+))==i); for(int i=n;i>=;i--)
{
mn[i][]=dat[i];
for(int j=;(i+(<<j)-)<=n;j++)
mn[i][j]=min(mn[i][j-],mn[i+(<<j-)][j-]);
}
for(int i=n;i>=;i--)
{
gcd[i][]=dat[i];
for(int j=;(i+(<<j)-)<=n;j++)
gcd[i][j]=GCD(gcd[i][j-],gcd[i+(<<j-)][j-]);
}
}
int Query_min(int l,int r)
{
int t=lg2[r-l+];
return min(mn[l][t],mn[r-(<<t)+][t]);
}
int Query_gcd(int l,int r)
{
int t=lg2[r-l+];
return GCD(gcd[l][t],gcd[r-(<<t)+][t]);
} bool check(int len)
{
tot=;
for(int i=;i<=n-len+;i++)
if(Query_min(i,i+len-)==Query_gcd(i,i+len-))
res[++tot]=i;
return tot>;
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&dat[i]);
pre(); int l=,r=n;
while(l<=r)
{
int mid=(l+r)>>;
if(check(mid)) l=mid+;
else r=mid-;
}
check(r);
printf("%d %d\n",tot,r-);
for(int i=;i<=tot;i++) printf("%d ",res[i]);
return ;
}
Problem B
如果只有询问用$ST$表$O(1)$询问
同时注意由于对一个数多次求$gcd$不会影响区间$gcd$值,因此可以直接用$ST$表维护$gcd$
C:
很像以前冒泡排序相关题的一个$Trick$:
由于交换序列是一个排列,因此每次交换后左右不可能再有交换,这样就拆为独立的子问题了
由于初始状态的值有规律是单调的,因此反向考虑问题:
对于当前区间$[l,r]$枚举交换位置$i$,如果交换$i,i+1$后左序列是$[l,l+i-1]$的一个排列则计算其贡献
$dp[l][r]=dp[l][l+i-1]*dp[l+i][r]*C^{i-1}_{r-l+1-2}$
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
#define pb push_back
typedef double db;
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=,MOD=1e9+;
int n,dat[MAXN];
ll C[MAXN][MAXN],dp[MAXN][MAXN]; ll dfs(int l,int r)
{
if(~dp[l][r]) return dp[l][r];
if(l==r) return dp[l][r]=;
//不能开全局……
int st[MAXN],top=;dp[l][r]=;
for(int i=;i<=n;i++)
if(dat[i]>=l&&dat[i]<=r)
st[++top]=dat[i]; for(int i=;i<top;i++)
{
swap(st[i],st[i+]);
bool f=;
for(int j=;j<=i;j++)
if(st[j]>=l+i){f=;break;}
for(int j=i+;j<=top;j++)
if(st[j]<l+i){f=;break;}
if(!f){swap(st[i],st[i+]);continue;} (dp[l][r]+=dfs(l,l+i-)*dfs(l+i,r)%MOD*C[r-l-][i-]%MOD)%=MOD;
swap(st[i],st[i+]);
}
return dp[l][r];
} int main()
{
scanf("%d",&n);
memset(dp,-,sizeof(dp));
for(int i=;i<=n;i++)
scanf("%d",&dat[i]);
for(int i=;i<=n;i++)
{
C[i][]=;
for(int j=;j<=i;j++)
C[i][j]=(C[i-][j]+C[i-][j-])%MOD;
}
dfs(,n-); if(~dp[][n-])
printf("%lld",dp[][n-]);
else puts("");
return ;
}
Problem C
注意这里每次处理的$[l,r]$的排列是$p$的子序列!
(处理到该子问题时能保证数在$p$中的相对位置不变)
D:
关键在于贡献为$2^{R+C}$,可以理解为对每一个子集算一次贡献
接下来算每个集合被包含的期望次数即可:
$res=\sum C^i_n*C^j_n*\frac{C^{k-num}_{m-num}}{C^k_m}$
其中$num$为如果$i$行$j$列全涂黑的个数,预处理组合数即可
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
#define pb push_back
typedef double db;
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=1e5+;
int n,m,k;
db res,cn[MAXN],cm[MAXN]; double cal(int i,int j)
{
int num=n*(i+j)-i*j;
return k-num<?:cm[num];
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
cn[]=cm[]=;
for(int i=;i<=n;i++) cn[i]=cn[i-]*(n-i+)/i;
for(int i=;i<=m;i++) cm[i]=cm[i-]*(k-i+)/(m-i+); for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
res+=cn[i]*cn[j]*cal(i,j);
printf("%.6lf",(res>1e99)?1e99:res);
return ;
}
Problem D
[ZROI 9.16模拟赛] Tutorial的更多相关文章
- [ZROI 9.15模拟赛] Tutorial
Link: 传送门 可能要补一补之前的题了 题目名字天(Sky)的(De)炭(C)好评啊…… A: 从买/卖物品的配对来考虑: 可以发现如果当前物品为卖,肯定从之前选最小的(无论其为买/卖),因为贡献 ...
- ZROI提高组模拟赛05总结
ZROI提高组模拟赛05总结 感觉是目前为止最简单的模拟赛了吧 但是依旧不尽人意... T1 有一半的人在30min前就A掉了 而我花了1h11min 就是一个简单的背包,我硬是转化了模型想了好久,生 ...
- ZROI 普及组模拟赛02总结
ZROI 普及组模拟赛02总结 先放[网址][http://zhengruioi.com/contest/96] 可能是有一段时间没有打这种正式的比赛了,今天打的很奇怪... T1 模拟水题 既然是普 ...
- [8.16模拟赛] 玩具 (dp/字符串)
题目描述 儿时的玩具总是使我们留恋,当小皮还是个孩子的时候,对玩具更是情有独钟.小皮是一个兴趣爱好相当广泛且不专一的人,这这让老皮非常地烦恼.也就是说,小皮在不同时刻所想玩的玩具总是会不同,而有心的老 ...
- 9 16 模拟赛&关于线段树上二分总结
1 考试时又犯了一个致命的错误,没有去思考T2的正解而是去简单的推了一下式子开始了漫漫找规律之路,不应该这样做的 为了得到规律虽然也打了暴力 但是还是打了一些不必要的程序 例如求组合数什么的比较浪费时 ...
- 2020.12.16 模拟赛x+1
A. 接力比赛 跑两遍背包,再进行一些玄学的剪枝 代码 #include<cstdio> #include<algorithm> #define rg register inl ...
- 10.16 NOIP模拟赛
目录 2018.10.16 NOIP模拟赛 A 购物shop B 期望exp(DP 期望 按位计算) C 魔法迷宫maze(状压 暴力) 考试代码 C 2018.10.16 NOIP模拟赛 时间:2h ...
- [NOIP2018模拟赛10.16]手残报告
[NOIP2018模拟赛10.16]手残报告 闲扯 炉石乱斗模式美滋滋啊,又颓到好晚... 上来T2先敲了树剖,看T1发现是个思博DP,然后没过大样例,写个暴力发现还是没过大样例!?才发现理解错题意了 ...
- 2017.1.16【初中部 】普及组模拟赛C组总结
2017.1.16[初中部 ]普及组模拟赛C组 这次总结我赶时间,不写这么详细了. 话说这次比赛,我虽然翻了个大车,但一天之内AK,我感到很高兴 比赛 0+15+0+100=115 改题 AK 一.c ...
随机推荐
- 如何写出优雅的js以及js特殊技巧
由于代码和解释都写在了github的readme内部,这里就直接附上github:https://github.com/jiangzhenfei/pretty-js/tree/master
- Android 搭建Linux系统
本文精心从网上搜罗出相关资料并整理,含有大量外部链接 安卓手机上安装linux大致分为两种方案 一.使用Linux Deploy 二.使用 Linux on Android 本文对Linux Depl ...
- webconfig的配置解析
<?xml version="1.0"?> <!--注意: 除了手动编辑此文件以外,您还可以使用 Web 管理工具来配置应用程序的设置.可以使用 Visual S ...
- Linux内核多线程实现方法 —— kthread_create函数【转】
转自:http://blog.csdn.net/sharecode/article/details/40076951 Linux内核多线程实现方法 —— kthread_create函数 内核经常需要 ...
- ProxySQL 故障
发现直接连接MGR节点是正常的,可以写入,但通过ProxySQL连接就无法show\select\insert 等 使用sysbench对ProxySQL报以下错误: FATAL: `thread_r ...
- redis的备份恢复
说明:默认rdb方式保存,redis支持主从和哨兵等,但是在某些情况下我们会单机跑,所以有时候我们就会需要设计到备份恢复 环境:原始redis:192.168.1.200 新redis:192.168 ...
- Serv-U设置允许用户更改密码【转】
最近,公司上了一套Serv-U10.5.0.6的ftp软件,应该是目前最新的版本了.上的第一天就遇到了一个问题,有领导发话了,他需要自己更改密码.找了N久才找到,分享一下. 点击管理界面的用户. 进入 ...
- Freemaker如何遍历key为non-string类型的map?
(一) 前置知识 Freemaker默认配置下会使用SimpleHash去包装后台传递的hashmap,下段摘抄自官方reference 同样,当你传递进去一个hashmap实例时,会替换为一个sim ...
- 制作自动化系统安装U盘
1.挂载CentOS6.6镜像 [root@test88 ~]# mkdir /application/tools -p [root@test88 ~]# cd /application/tools/ ...
- Webcollector应用(一)
webcollector是一个开源的Java网络爬虫框架.最近的爬虫改用java写了,对这一周的工作进行简要总结.对于内部机制了解不深入,主要侧重在应用. 一.环境搭建 需要安装一个webcollec ...