HGOI 20190709 题解
Problem A 紫色激情
一个序列$\{a_n\}$,求出方差最大的子序列。
其中方差 [l,r] 的定义是$S^2 = \frac{1}{n} \sum\limits_{i=l}^{r} (x_i-\bar{x})^2$
对于100%的数据满足$n \leq 10^3$
Sol : 直接推一波公式就可以前缀和优化了。
${ S_{l,r} }^2 = -\bar{x}^2 +\frac{\sum_{i=l}^r {x_i}^2}{n}$
时间复杂度$O(n^2)$
# include<bits/stdc++.h>
# define int long long
using namespace std;
const int N=2e3+;
int s1[N],s2[N];int n;
inline int read()
{
int X=,w=; char c=;
while(c<''||c>'') {w|=c=='-';c=getchar();}
while(c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
return w?-X:X;
}
inline void write(int x)
{
if (x<) x=-x,putchar('-');
if (x>) write(x/);
putchar(x%+'');
}
signed main()
{
n=read();
for (int i=;i<=n;i++) {
int t=read();
s1[i]=s1[i-]+t;
s2[i]=s2[i-]+t*t;
}
double ans=-1e9; int ansl=,ansr=;
for (int l=;l<=n;l++)
for (int r=l;r<=n;r++) {
double t=-(double)(s1[r]-s1[l-])*(s1[r]-s1[l-])/(double)(r-l+)/(double)(r-l+);
double w=(double)(s2[r]-s2[l-])/(double)(r-l+);
if (t+w>ans) { ans=t+w; ansl=l; ansr=r;}
}
write(ansl);putchar(' ');write(ansr); putchar('\n');
return ;
}
passion.cpp
Problem B 克罗地亚狂想曲
共有$n$个节点,从每个节点可以向前面一个节点连一条边,而如果和后面一个节点的连边将被忽略。
两个相连节点之间有一条连边,可以直接经过,找出一条访问的路径,使得每个节点被经过最多2次,
经过路径上点值之和最大。
对于100%的数据 , $n \leq 3\times 10^5 $
Sol: 显然,向前连边的这个过程是没有后效性的,所以可以进行动态规划。
而每个节点最多只能被经过2次保证了一次转移的合法性。
设$f_i$表示走到节点$i$时候最大值。
如果当前元素没有向前连边,那么答案就从上一节点走来,$f_i = f_{i-1} + a_i$
如果当前元素有向前连边到$j$那么可以考虑从$j$过来在经过$j$,在走到$i$,再接下去走。
这等价于$j->i$的路径被累加了$2$次,那么转移方程就是$f_i = f_{j-1} + 2 \sum\limits_{k=j}^{i} a_k$
然后那个$\sum$累加可以用前缀和优化掉,这样这个DP就是线性的了。
复杂度$O(n)$
# include <bits/stdc++.h>
# define int long long
using namespace std;
const int N=3e5+;
int from[N],f[N],s[N],n;
inline int read()
{
int X=,w=; char c=;
while(c<''||c>'') {w|=c=='-';c=getchar();}
while(c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
return w?-X:X;
}
inline void write(int x)
{
if (x<) x=-x,putchar('-');
if (x>) write(x/);
putchar(x%+'');
}
signed main()
{
n=read();
for (int i=;i<=n;i++) {
int t=read();
if (t>i) continue;
from[i]=t;
}
for (int i=;i<=n;i++) {
int t=read();
s[i]=s[i-]+t;
}
for (int i=;i<=n;i++) {
f[i]=f[i-]+s[i]-s[i-];
if (from[i]!=) f[i]=max(f[from[i]-]+*(s[i]-s[from[i]-]),f[i]);
}
write(f[n]);putchar('\n');
return ;
}
rhapsody.cpp
Problem C 花之舞
给出一个字符串中,求该字符串中最大不重复双倍回文串覆盖。
对于100%的数据,$ len(s) \leq 10^3 $
Sol : 首先我们可以通过字符串Hash的做法判定一个串是不是回文串,这样只需要一遍$O(n)$的预处理,再$O(1)$判定即可。
然后我们可以$O(n^2)$枚举从$i$开始的所有双倍回文串,然后可以使用类似线段覆盖的DP做出最大不重复双倍回文串覆盖。
最终的复杂度是$O(n^2)$的。
# include<bits/stdc++.h>
# define int long long
using namespace std;
const int mo=1e9+;
const int base=;
const int N=1e3+;
int p[N],a[N],hash1[N],hash2[N],f[N];
int n;
vector<int>v[N];
inline int read()
{
int X=,w=; char c=;
while(c<''||c>'') {w|=c=='-';c=getchar();}
while(c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
return w?-X:X;
}
inline void write(int x)
{
if (x<) x=-x,putchar('-');
if (x>) write(x/);
putchar(x%+'');
}
int gethash(int num,int l,int r)
{
if (num==) return ((hash1[r]-hash1[l-]*p[r-l+]%mo)%mo+mo)%mo;
else return ((hash2[r]-hash2[l-]*p[r-l+]%mo)%mo+mo)%mo;
}
bool check(int l,int r)
{
if ((r-l+)&) {
int pos=(l+r)/,len=(r-l)/;
if (gethash(,pos,pos+len)==gethash(,n+-pos,n+-pos+len)) return ;
else return ;
} else {
int pos1=(l+r)/,pos2=pos1+,len=(r-l-)/;
if (gethash(,pos2,pos2+len)==gethash(,n+-pos1,n+-pos1+len)) return ;
else return ;
}
}
void fun(int pos)
{
for (int mid=(n+-pos)/;mid>=;mid--)
if (check(pos,pos+mid-)&&check(pos+mid,pos+*mid-)&&gethash(,pos,pos+mid-)==gethash(,pos+mid,pos+*mid-))
v[pos].push_back(pos+*mid-);
}
signed main()
{
// freopen("dance.in","r",stdin);
// freopen("dance.out","w",stdout);
n=read(); p[]=;
for (int i=;i<=n;i++)
a[i]=read(),p[i]=p[i-]*base%mo;
for (int i=;i<=n;i++)
hash1[i]=(hash1[i-]*base%mo+a[i])%mo;
int u=;
for (int i=n;i>=;i--) u++,hash2[u]=(hash2[u-]*base%mo+a[i])%mo;
for (int i=;i<=n;i++) fun(i);
for (int i=n;i>=;i--) {
f[i]=f[i+];
for (int j=;j<v[i].size();j++)
f[i]=max(f[i],f[v[i][j]+]+(v[i][j]-i+));
}
write(f[]); putchar('\n');
return ;
}
dance.cpp
HGOI 20190709 题解的更多相关文章
- HGOI 20181028 题解
HGOI 20181028(复赛备考) /* 真是暴力的一天,最后一题MLE?由于数组开得太大了!!! 270滚粗 考场上好像智商高了很多?!(假的) */ sol:暴力求解,然后没有数据范围吐槽一下 ...
- HGOI 20190310 题解
/* 又是又双叒叕WA的一天... 我太弱鸡了... 今天上午打了4道CF */ Problem 1 meaning 给出q组询问,求下列函数的值$ f(a) = \max\limits_{0 < ...
- HGOI 20190303 题解
/* 记一串数字真难. 5435 今天比赛又是hjcAK的一天. 今天开题顺序是312,在搞T1之前搞了T3 昨天某谷月赛真是毒瘤. 但是讲评的同学不错,起码T4看懂了... 构造最优状态然后DP的思 ...
- HGOI 20180224 题解
/* The Most Important Things: ljc chat with fyh on QQTa说期末考Ta数学74分感觉不好但是我觉得fyh是地表最强的鸭~~(of course en ...
- HGOI 20190218 题解
/* 又是AK局... hjc又双叒叕AK了... Hmmm...我侥幸 */ Problem A card 给出无序序列a[]可以选择一个数插入到合适的位置作为一次操作,至少多少次操作后可以把序列变 ...
- HGOI 20190217 题解
/* for me,开训第一天 /beacuse 文化课太差被抓去补文化课了... 看一眼题 : AK局? 但是,Wa on test #10 in problem C 290! (就差那么一咪咪) ...
- HGOI 20181103 题解
problem:把一个可重集分成两个互异的不为空集合,两个集合里面的数相乘的gcd为1(将集合中所有元素的质因数没有交集) solution:显然本题并不是那么容易啊!考场上想了好久.. 其实转化为上 ...
- HGOI 20181101题解
/* 又是爆0的一天(不知道今年高考难不难,反正今天(信息学)真的难!) */ solution:对于两个数相加,有一个显然的结论就是要么不进位(相对于位数大的),要么(进最多一位) 然后对于整个数组 ...
- HGOI 20191108 题解
Problem A 新婚快乐 一条路,被$n$个红绿灯划分成$n+1$段,从前到后一次给出每一段的长度$l_i$,每走$1$的长度需要$1$分钟. 一开始所有红绿灯都是绿色的,$g$分钟后所有红绿灯变 ...
随机推荐
- (5.6)mysql高可用系列——MySQL Utilities 管理工具
关键词:mysql工具集,mysql管理工具,mysql utilities [1]安装mysql utilities cd /download wget https://cdn.mysql.com/ ...
- 小记---------spark优化之更优分配资源
spark优化:在一定范围之内,增加资源与性能的提升是成正比的. 因此, 一个cpu core 执行一个task线程. task数: 若有 cpu core 2个.num-execu ...
- 【pytorch】学习笔记(一)-张量
pytorch入门 什么是pytorch PyTorch 是一个基于 Python 的科学计算包,主要定位两类人群: NumPy 的替代品,可以利用 GPU 的性能进行计算. 深度学习研究平台拥有足够 ...
- GitHub从小白到熟悉<一>
注册开始
- BM求线性递推模板(杜教版)
BM求线性递推模板(杜教版) BM求线性递推是最近了解到的一个黑科技 如果一个数列.其能够通过线性递推而来 例如使用矩阵快速幂优化的 DP 大概都可以丢进去 则使用 BM 即可得到任意 N 项的数列元 ...
- C++ 数组操作符重载、函数对象分析、赋值操作符
string类型访问单个字符 #include <iostream> #include <string> #include <sstream> using name ...
- Android Studio 配置Gradle总结
一, 问题:①换个新电脑安装完Android Sutdio第一次打开一个工程巨慢怎么办? ② 手动配置Gradle Home为什么总是无效? ③ 明明已经下载了Gradle,配置了gradle hom ...
- Reducing Snapshots to Points: A Visual Analytics Approach to Dynamic Network Exploration
---恢复内容开始--- 分析静态网络的方法:(1)节点链接图 (2)可视化邻接矩阵 and(3)hierarchical edge bundles. 分析网络演变的方法:(1)时间到时间的映射和(2 ...
- vue-时间插件,效果见图
<template> <div class="select-time-wrapper"> <h5 class="titie"> ...
- python之itertools
Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数. count 创建一个迭代器,生成从n开始的连续整数,如果忽略n,则从0开始计算(注意:此迭代器不支持长整数) 如果超出 ...