ZJOI2022选做
\(ZJOI2022\)
众数
发现并不存在\(poly(log(n))\)的做法,那么尝试\(n\sqrt n\)
套路的按照出现次数分组,分为大于\(\sqrt n\)和小于\(\sqrt n\)
然后分别维护,小数对小数的贡献为什么要算两次,我们贡献是一段区间众数\(-\)这个数出现次数,是因为貌似一边连续从开始一段颜色需要考虑
//根号分治比较显然,分块维护不是很可行
//出现次数大于根号n,最多有根号n个,然后枚举哪些颜色变成这个颜色
//然后找一个合适的位置转移过去
//出现次数小于根号,枚举变化位置即可
//我们的贡献计算方式分为
//大于根号的向大于根号的贡献
//大于根号的向小于根号的贡献
//小于根号的向大于根号的贡献
//小于根号的向小于根号的贡献
//前三种都在第一次处理时解决
//考虑怎么贡献,我们可以枚举对别的的贡献
//那么我们每次暴力修改一段区间,更新内部的
//我们Max求的一直是,我们能最多多多少
#include<bits/stdc++.h>
#define MAXN 200005
using namespace std;
int a[MAXN],b[MAXN],t[MAXN],bc[MAXN],sum[MAXN],Max[MAXN],Lim,tot,n;
vector<int>poz[MAXN];
map<int,int>mp;
void solve()
{
for(int i=1;i<=n;i++) sum[i]=0;
for(int i=1;i<=n;i++)
{
if(t[a[i]]<=Lim)
{
int p=lower_bound(poz[a[i]].begin(),poz[a[i]].end(),i)-poz[a[i]].begin();
//我们这一步只需要求区间众数就好了
//贡献就是区间众数-本数字出现次数
// cout<<"now: "<<a[i]<<" "<<i<<" "<<p<<"\n";
for(int j=p,l,r;j>=0;j--)
{
if(j==0) l=1;
else l=poz[a[i]][j-1]+1;
r=poz[a[i]][j];
// cout<<j<<" "<<poz[a[i]].size()<<" "<<l<<" "<<r<<"\n";
Max[a[i]]=max(Max[a[i]],sum[l]-(p-j));
while(l<=r&&sum[r]<p-j+1) sum[r--]=p-j+1;
}
}
}
}
void sol()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
mp.clear();tot=0;
memset(t,0,sizeof(t));
memset(bc,0,sizeof(bc));
memset(Max,0,sizeof(Max));
for(int i=1;i<=n;i++) poz[i].clear();
sort(b+1,b+1+n);
for(int i=1;i<=n;i++)
{
if(!mp[b[i]]) mp[b[i]]=++tot,bc[tot]=b[i];
// t[mp[b[i]]]++;
// poz[mp[b[i]]].push_back(i);
}
for(int i=1;i<=n;i++) a[i]=mp[a[i]],t[a[i]]++,poz[a[i]].push_back(i);
Lim=sqrt(n);
for(int i=1;i<=tot;i++)
{
if(t[i]>Lim)
{
sum[0]=0;
for(int j=1;j<=n;j++)
{
sum[j]=sum[j-1]+(int)(a[j]==i);
}
int l=0,s=0;
//我们其余的对当前贡献相当于一个最大子段和
for(int j=1;j<=tot;j++)
{
int N=t[j],l=0,r,s=0;
for(int k=0;k<N;k++)
{
r=poz[j][k];
s=max(0,s-(sum[r]-sum[l]))+1;
Max[i]=max(Max[i],s);
l=r;
}
l=s=0;
for(int k=0;k<N;k++)
{
r=poz[j][k];
s=max(s,0)+sum[r]-sum[l];
Max[j]=max(Max[j],s--);
l=r;
}
}
}
}
solve();
reverse(a+1,a+1+n);
for(int i=1;i<=tot;i++)
{
reverse(poz[i].begin(),poz[i].end());
for(int j=0;j<poz[i].size();j++) poz[i][j]=n-poz[i][j]+1;
}
solve();
int Ans=0;
for(int i=1;i<=tot;i++)
{
Max[i]+=t[i];
Ans=max(Ans,Max[i]);
}
cout<<Ans<<"\n";
for(int i=1;i<=tot;i++)
{
if(Max[i]==Ans) cout<<bc[i]<<"\n";
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--) sol();
}
\(T2\)
计数题滚出OI
一道(对我)并不签到的(对大家而已的)签到题
首先我们可以枚举\(2^n\)的状态,表示第一个树的叶子集合,然后方案也比较好求
树的形态就是在保证每个点找一个前面的点然后把叶子不对的容斥出去,子集容斥就好了\(?\)
\(O(2^n n)\)的暴力直接枚举两树形态,转移时候直接把非叶子节点标记为\(1\)即可
然后发现合并的时候\(dp[n][x]=dp[n][x_{rev}]\)
就很\(nb\)了,意思就是,我们得到了两棵树状态确定之后,他们的情况数是相同的
我们就先确定一个树的状态
\(f(S)\)为恰好\(S\)不是叶子的方案数
\(g(S)\)为钦定除了\(S\)之外的点都是叶子(\(S\)之内可是可不是)的方案数
\(g(S)\)易得
\(g(S)=\Pi_{i=2}^n\sum_{j\in S}[j<i]\)
直接枚举前面的可以成为非叶子的去选
\(f(S)=\sum_{T\subset S,1\not\in T}(-1)^{|T|}g(S\backslash T)\)
我们要求\(\sum_S f^2(S)\)
需要拆开计算
\(\large\sum_S f^2(S)=\sum_S\sum_{T_1\in S}\sum_{T_2\in S}(-1)^{|T_1|+|T_2|}\large(\small \Pi_{i=2}^n\sum_{j\in S\backslash T_1}[j<i]\large)\large(\small \Pi_{i=2}^n\sum_{j\in S\backslash T_2}[j<i]\large)\)
化简一下
\(\sum_{S}\sum_{T_1\in S}\sum_{T_2\in S}(-1)^{|T_1|+|T_2|}\Pi_{i=2}^n (\sum_{j\in S\backslash T_1 [j<i]})(\sum_{j\in S\backslash T_1} [j<i])\)
到这就可以\(dp\)了
具体的话,我们仅需要枚举我们当前的\(i\)在哪些里面做贡献就好了,把后面两个\(\sum\)压入状态
#include<bits/stdc++.h>
#define int long long
#define MAXN 505
using namespace std;
int dp[2][MAXN][MAXN];
int n,mod;
signed main()
{
scanf("%lld%lld",&n,&mod);
dp[0][1][1]=1;
for(int i=1;i<n;i++)
{
int now=i%2;
int pre=now^1;
memset(dp[now],0,sizeof(dp[now]));
for(int j=1;j<=i;j++)
{
for(int k=1;k<=i;k++)
{
int val=dp[pre][j][k]*j%mod*k%mod;
dp[now][j][k]+=2*val;
dp[now][j+1][k+1]+=val;
dp[now][j+1][k]-=val;
dp[now][j][k+1]-=val;
}
}
int Ans=0;
for(int j=1;j<=i+1;j++)
{
for(int k=1;k<=i+1;k++)
{
(Ans+=dp[now][j][k])%=mod;
}
}
cout<<(Ans+mod)%mod<<"\n";
}
}
ZJOI2022选做的更多相关文章
- [SDOI2016]部分题选做
听说SDOI蛮简单的,但是SD蛮强的.. 之所以是选做,是因为自己某些知识水平还不到位,而且目前联赛在即,不好花时间去学sa啊之类的.. bzoj4513储能表&bzoj4514数字配对 已写 ...
- 20175221 《Java程序设计》迭代和JDB(课下作业,选做):
20175221 <Java程序设计> 迭代和JDB(课下作业,选做): 任务详情 1 使用C(n,m)=C(n-1,m-1)+C(n-1,m)公式进行递归编程实现求组合数C(m,n)的功 ...
- MyOD(课下作业,选做)
MyOD(课下作业,选做) 代码要求 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt XXX2.b ...
- 迭代和JDB(课下作业,选做)
迭代和JDB(课下作业,选做) 题目要求 1 使用C(n,m)=C(n-1,m-1)+C(n-1,m)公式进行递归编程实现求组合数C(m,n)的功能 2 m,n 要通过命令行传入 3 提交测试运行截图 ...
- 20175312 2018-2019-2 《Java程序设计》第6周课下选做——类定义
20175312 2018-2019-2 <Java程序设计>第6周课下选做--类定义 设计思路 1.我觉得Book其实就是一个中转的作用,由测试类Bookself通过Book输入数据,然 ...
- 20175314薛勐 MyOD(课下作业,选做)
MyOD(课下作业,选做) 要求 编写MyOD.java 用java MyOD XXX实现Linux下od -tx -tc XXX的功能 思路 伪代码: 读取命令行输入的参数(文件名) 以16为每个字 ...
- 20155228 2017-11-19 实现mypwd(选做,加分)
20155228 2017-11-19 实现mypwd(选做,加分) 题目和要求 学习pwd命令 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 实现mypwd 测试mypwd ...
- 2017-2018-2 20165312 课下选做 MySort
2017-2018-2 20165312 课下选做 MySort 题目描述 模拟实现Linux下Sort -t : -k 2的功能,参考 Sort的实现. import java.util.*; pu ...
- 「LOJ2000~2023」各省省选题选做
「LOJ2000~2023」各省省选题选做 「SDOI2017」数字表格 莫比乌斯反演. 「SDOI2017」树点涂色 咕咕咕. 「SDOI2017」序列计数 多项式快速幂. 我们将超过 \(p\) ...
随机推荐
- sqlalchemy模块介绍、单表操作、一对多表操作、多对多表操作、flask集成.
今日内容概要 sqlalchemy介绍和快速使用 单表操作增删查改 一对多 多对多 flask集成 内容详细 1.sqlalchemy介绍和快速使用 # SQLAlchemy是一个基于 Python实 ...
- 第一篇:实时网络日志分析器和交互式查看器--GoAccess安装
介绍 GoAccess是一个开源的实时网络日志分析器和交互式查看器,可以在* nix 系统或通过浏览器的终端中运行. 它为需要动态可视化服务器报告的系统管理员提供快速且有价值的HTTP统计信息. 特征 ...
- 博弈论(nim游戏,SG函数)
说到自己,就是个笑话.思考问题从不清晰,sg函数的问题证明方法就在眼前可却要弃掉.不过自己理解的也并不透彻,做题也不太行.耳边时不时会想起alf的:"行不行!" 基本的小概念 这里 ...
- 揭秘华为云GaussDB(for Influx)最佳实践:hint查询
摘要:GaussDB(for Influx)通过提供hint功能,在单时间线的查询场景下,性能有大幅度的提升,能有效满足客户某些特定场景的查询需求. 本文分享自华为云社区<华为云GaussDB( ...
- python基础学习8
python基础学习8 内容概要 字典的内置方法 元组的内置方法 集合的内置方法 垃圾回收机制 内容详情 字典的内置方法 一.类型转换 res = dict(name='jason', pwd=123 ...
- Java学习-第一阶段-第一节:Java概述
JAVA概述 Java版本 原网址(https://www.oracle.com/java/technologies/java-se-support-roadmap.html) Oracle 将仅将某 ...
- Mybatis架构原理(二)-二级缓存源码剖析
Mybatis架构原理(二)-二级缓存源码剖析 二级缓存构建在一级缓存之上,在收到查询请求时,Mybatis首先会查询二级缓存,若二级缓存没有命中,再去查询一级缓存,一级缓存没有,在查询数据库; 二级 ...
- CentOS中实现基于Docker部署BI数据分析
作为一个专业小白,咱啥都不懂. linux不懂,docker不懂. 但是我还想要完成领导下达的任务:在linux中安装docker后部署数据可视化工具.作为一名敬业 的打工人摆烂不可以,躺平不可以,弱 ...
- Elasticsearch学习系列四(聚合搜索)
聚合分析 聚合分析是数据库中重要的功能特性,完成对一个查询的集中数据的聚合计算.如:最大值.最小值.求和.平均值等等.对一个数据集求和,算最大最小值等等,在ES中称为指标聚合,而对数据做类似关系型数据 ...
- VisionPro · C# · 创建项目
将 VisionPro 引入 C# 项目程序中需要执行以下操作: 1.更改项目程序.NET框架: 2.添加编程引用: 3.添加界面设计控件引用: VisionPro 不同版本对应不同的 .NET 框架 ...