当前位置: 首页 > news >正文

GJOI 10.23 题解

1.洛谷 P4552 IncDec Sequence

题意

给定一个长度为 nnn 的数列 a1,a2,⋯,an{a_1,a_2,\cdots,a_n}a1,a2,,an,每次可以选择一个区间[l,r][l,r][l,r],使这个区间内的数都加 111 或者都减 111

请问至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列有多少种。

1≤n≤105,ai∈[0,231]1\le n\le 10^5, a_i \in[0, 2^{31}]1n105,ai[0,231]

思路

考虑操作本质,区间 +1+1+1 就是让差分数组左端 +1+1+1 右端 −1-11−1-11 反之亦然。最终所有数都一样,就是让除了 111 之前、nnn 之后的差分值意外,其它差分值全部变成 000。而且不难发现 111 前差分值决定了相等数列的数是什么 。

于是保证操作次数最少,必然是中间的绝对值,分别匹配一对正的、负的差分值分别 −1,+1-1,+11,+1,直到有一个变为 000,再操作其它的。最后可能剩下一个正数或负数,此时让该差分值和 111 前或 nnn 后的差分值操作,直到该差分值变为 000。考虑快速计算次数,不难发现可以分别计算正负差分值之和的绝对值 s1,s2s1,s2s1,s2max⁡(s1,s2)\max(s1,s2)max(s1,s2) 即最少操作次数。

但种数呢?剩下最后一个差分值 ccc 时,整个数列的长成前面一堆 aaa 后边一堆 bbb,满足 c=b−ac=b-ac=ba,可以随意对左右两边操作,最后取值就为 [a,b][a,b][a,b][b,a][b,a][b,a],种数为 ∣b−a∣+1=∣c∣+1|b-a|+1=|c|+1ba+1=c+1

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=1e5+9;
ll n;
ll a[N],b[N],tot;
ll c[N];
int main()
{freopen("qingfeng.in","r",stdin);freopen("qingfeng.out","w",stdout); scanf("%lld",&n);ll tot=0;for(int i=1;i<=n;i++)scanf("%lld",&a[i]);for(int i=1;i<=n;i++)c[i]=a[i]-a[i-1];ll s1=0,s2=0;for(int i=2;i<=n;i++){if(c[i]>0)s1+=c[i];else s2-=c[i];}printf("%lld\n%lld",max(s1,s2),abs(s1-s2)+1);return 0;
}

2.洛谷 P2403 SDOI2010 所驼门王的宝藏

我的博客。

3.CF710F String Set Queries

题意

在这里插入图片描述
强制在线要求参考原题面。

操作次数 1≤T≤3×1051\le T\le 3\times 10^51T3×105,输入字符串长度和 S=∑∣s∣≤3×105S=\sum |s|\le 3\times 10^5S=s3×105

思路

查询是 ACAM 模板说是,但是早就被我忘得一干二净了,这题的操作二进制分组优化,具体实现可以参考这篇博客,还是等我复习完之后再回来补吧。这里讲一种优美的暴力做法。

赛时只写了个近似 O(Tn)O(Tn)O(Tn),其中 TTT 在于加的字符串个数,nnn 为查询模式串长度。发现相同长度为 xxx 的集合串,TTT 次在长度为 nnn 的模式串上 O(n−x)O(n-x)O(nx) 匹配,很费时间。

但是我们发现,nnn 每个长度为 xxx 的子串至多匹配一种长度为 xxx 的集合串。于是我们想要按照长度分类所有集合串。这样就不需要重复地扫 O(n−x)O(n-x)O(nx) 了。

具体地,对每个长度开一个 unordered_map 存集合串哈希值,通过截取模式串区间哈希值,在长度 xxxunordered_mapO(1)O(1)O(1) 获取个数(可重集)。

但是 xxx 不会很多吗?题目说 S≤3×105S\le 3\times 10^5S3×105,对于互不相同的长度 xix_ixi∑xi≤3×105\sum x_i\le 3\times 10^5xi3×105,最劣情况从 111 开始加,种数是 S\sqrt{S}S 级别的。

于是均摊复杂度为 O(nS)O(n\sqrt{S})O(nS),时限有 3s 宽松,两项都跑不满。

代码

#pragma GCC optimise(2)
#pragma GCC optimise(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=3e5+9,B=550;
const ll base=19260817,mod=1e9+7;
ll Q,op;
ll id[N],tot,bh[B];
ll pw[N];
void init()
{pw[0]=1;for(int i=1;i<N;i++)pw[i]=pw[i-1]*base%mod;
}
char s[N];
unordered_map<ll,ll>S[B];
ll change(char c)
{return c-'a'+1;
}
ll ha[N];
ll getHash(ll l,ll r)
{return (ha[r]-ha[l-1]*pw[r-l+1]%mod+mod)%mod;
}
int main()
{freopen("suoyong.in","r",stdin);freopen("suoyong.out","w",stdout);scanf("%lld",&Q);init();while(Q--){scanf("%lld%s",&op,s+1);ll n=strlen(s+1);for(int i=1;i<=n;i++)ha[i]=(ha[i-1]*base%mod+change(s[i]))%mod;if(op==1){if(!id[n])id[n]=++tot,bh[tot]=n;S[id[n]][ha[n]]++;}if(op==2){S[id[n]][ha[n]]--;}if(op==3){ll ret=0;for(int i=1;i<=tot;i++){for(int j=bh[i];j<=n;j++){if(S[i].count(getHash(j-bh[i]+1,j)))ret+=S[i][getHash(j-bh[i]+1,j)];}}printf("%lld\n",ret);//	fflush(stdout);}}return 0;
}

反思

还是那句话,打暴力之前也应该好好思考,不要忘记考虑根号算法,有时比较好写并且跑得很快!

4.CF1810G The Maximum Prefix

题意

题目传送门,建议前往原题阅读题意,样例及其解释。

思路

对我而言是很新的期望 dp 呢。期望的答案总结为“概率×值”,就是实际得分里面赛得分概率。

前缀长度为 kkk,若钦定最大前缀和为 xxx,这要求:

  • ∀0≤i≤k,si≤x\forall 0\le i\le k,s_i\le x∀0ik,six
  • ∃0≤i≤k,si=x\exist 0\le i\le k,s_i=x∃0ik,si=x

才能拿到 hxh_xhx 的分数,对于前缀长度 kkk,我们要算出最大前缀和取到 xxx 的概率,然后乘上 hxh_xhx

不妨设 fi,j,opf_{i,j,op}fi,j,op 表示前 iii 个数,sis_isi 距离某个钦定最大值还差 jjj(钦定值 ∈[0,i]\in [0,i][0,i],根据题目要求取不到负数),之前是否达成过钦定值 op=0/1op=0/1op=0/1,的期望得分。初始化 f0,j,[j=0]=hjf_{0,j,[j=0]}=h_jf0,j,[j=0]=hj,相当于后面要算的只有概率了。根据上文的条件,只要前面达到过钦定值(op=1op=1op=1)就是合法的。

考虑 aia_iai 填什么:

  • ai=1a_i=1ai=1,距离钦定值的差距 −1-11fi,j,op∨[j=0]←fi−1,j+1,op×pif_{i,j,op\vee [j=0]}\leftarrow f_{i-1,j+1,op}\times p_ifi,j,op[j=0]fi1,j+1,op×pi
  • ai=−1a_i=-1ai=1,距离钦定值差距 +1+1+1fi,j,op∨[j=0]←fi−1,j−1,op×(1−pi)f_{i,j,op\vee[j=0]}\leftarrow f_{i-1,j-1,op}\times (1-p_i)fi,j,op[j=0]fi1,j1,op×(1pi)

前缀长度为 kkk 的答案为 ∑j=0ifk,j,1\sum\limits_{j=0}^i f_{k,j,1}j=0ifk,j,1

这题似乎卡空间?可以滚动数组优化。然后记得勤取模。具体细节见代码。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=5004,mod=1e9+7;
int Q,n;
ll p[N],q[N],h[N];
ll qpow(ll x,int k)
{ll ret=1;while(k){if(k&1)ret=ret*x%mod;x=x*x%mod;k>>=1;}return ret;
}
ll f[2][N][2];
void clean()
{memset(f,0,sizeof(f));
}
int main()
{freopen("ziliang.in","r",stdin);freopen("ziliang.out","w",stdout);scanf("%d",&Q);while(Q--){scanf("%d",&n);clean();for(int i=1;i<=n;i++){ll x,y;scanf("%lld%lld",&x,&y);p[i]=x*qpow(y,mod-2)%mod;q[i]=(y-x)*qpow(y,mod-2)%mod;}for(int i=0;i<=n;i++)scanf("%lld",&h[i]);for(int j=0;j<=n;j++)f[0][j][j==0]=h[j];for(int i=1;i<=n;i++){int now=i&1,las=now^1;memset(f[now],0,sizeof(f[now]));ll ret=0;for(int j=0;j<=n;j++){for(int op=0;op<=1;op++){if(j<n)f[now][j][op|(j==0)]=(f[now][j][op|(j==0)]+f[las][j+1][op]*p[i]%mod)%mod;if(j>0)f[now][j][op|(j==0)]=(f[now][j][op|(j==0)]+f[las][j-1][op]*q[i]%mod)%mod;}ret=(ret+f[now][j][1])%mod;}printf("%lld ",ret);}puts("");}return 0;
}

反思

还是期望 dp 这类题目见得太少,以后要适当接触。

附一道期望 dp 的入门题目:P1365 WJMZBMR打osu! / Easy

http://www.dtcms.com/a/537797.html

相关文章:

  • 《HTTP 的进化史:从 1.0 到 3.0 的飞跃》
  • wordpress 首页导航神马搜索seo优化排名
  • 淄博做网站小程序的公司域名免费注册0元注册
  • Vue3 项目创建指南(Vue-CLI vs Vite 对比)
  • 为IvorySQL增添PACKAGE语法帮助
  • 软件开发公司网站模板所有网站都要备案吗
  • 牛客101:二叉树
  • LangChain最详细教程之Chains
  • 声纹识别:声音中的“指纹”重塑无感身份认证
  • RDPWD!ShareClass::UPSendOrders函数中的RDPWD!ShareClass::SC_FlushAndAllocPackage函数分析
  • 怎么建设网站容易被百度抓取app开发公司 无冬
  • 站长字体网页美工培训班
  • 深圳营销型网站dz论坛怎么做视频网站吗
  • 有哪些网站是拐角型wordpress 文章摘要 插件
  • 网站开发项目经验百度移动端网站
  • pc端网站布局中国建设银行网站转账
  • 临沂做外贸网站的公司给一个装修公司怎么做网站
  • Java的异常处理机制
  • 大连三大网络推广网站wordpress百度收录搜索
  • 标准化开放 API 对接工具类 OpenApiHttp 深度解析:高效、安全的接口集成方案
  • 网站空间域名能不能自己续费专注做蔬菜的网站
  • 泰安vx百度关键词如何优化
  • 通感算控一体化-AIBOX提供无人机BVLOS(超视距)飞行的无线通信增强解决方案:5G蜂窝+无线自组网双链路的C2通信方案
  • 东营网站seo顾问一个简单的网站搭建教程
  • 如何检测电脑SSD健康状态?
  • 胶州建设信息网站课件模板下载免费
  • 建立网站顺序网站宽度设计
  • Spring Boot3零基础教程,远程调用 WebClient,笔记74
  • 网上书店电子商务网站建设专业网站开发技术
  • MySQL高可用方案MICmysqlCluster+mysqlRouter