[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 ...
随机推荐
- 引用类型 ( 对象定义 )——Array 类型
本文地址:http://www.cnblogs.com/veinyin/p/7607293.html 一个数组中可以存储不同类型的值,可以混合存储数字.字符串.对象等 1 创建数组 1.1 构造函数 ...
- FastDFS图片服务器java后台的简单调用
工具类: package com.liveyc.common.fdfs; import org.apache.commons.io.FilenameUtils; import org.csource. ...
- js刷题:leecode 25
原题:https://leetcode.com/problems/reverse-nodes-in-k-group/ 题意就是给你一个有序链表.如1->2->3->4->5,还 ...
- 2017ACM暑期多校联合训练 - Team 3 1003 HDU 6058 Kanade's sum (模拟)
题目链接 Problem Description Give you an array A[1..n]of length n. Let f(l,r,k) be the k-th largest elem ...
- vc 播放音乐
#include <vfw.h> #pragma comment(lib,"vfw32.lib") ● 简单实现 要实现一个播放器,首先要先建立一个MF ...
- lspci 虚拟机网卡对应关系
我这个办法有点笨: 到 /sys/devices/ 下去搜索网卡 eth*,找到网卡对应的PCI 总线位置,例如:05:00.0. 然后通过 "lspci -s 05:00.0" ...
- elk系列7之通过grok分析apache日志【转】
preface 说道分析日志,我们知道的采集方式有2种: 通过grok在logstash的filter里面过滤匹配. logstash --> redis --> python(py脚本过 ...
- 在Ubuntu上使用pip安装错误 read timed out 处理方法
在终端输入 pip --default-timeout=1000 install -U pip 也就是修改超时时间.
- 防范SQL注入
使用占位符的方式写查询语句hibernate
- 对cgic的理解——name选项
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "cgic.h" ...