CSP16

news/2024/11/17 13:00:48/文章来源:https://www.cnblogs.com/wlesq/p/18348908

image

这题,唯一坑点,子序列是不连续的
注意,子序列可以不连续,子串必须连续。
有一个很显然的暴力

点击查看代码
int dp[N][N],n,p[N],q[N];
int main()
{speed();freopen("in.in","r",stdin);freopen("out.out","w",stdout);cin>>n;for(int i=1;i<=n;i++)cin>>p[i];for(int i=1;i<=n;i++)cin>>q[i];for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){dp[i][j]=max(dp[i-1][j],dp[i][j-1]);if(q[j]%p[i]==0){dp[i][j]=max(dp[i-1][j-1]+1,dp[i][j]);}}}cout<<dp[n][n]<<endl;return 0;
}

优化就是拿树状数组优化,顺便滚掉一位,注意啊倒序遍历,否则会更新错误,预处理处每个\(p_i\)对应的倍数
复杂度\(O(n\ln n\log n)\)

点击查看代码
#include <bits/stdc++.h>
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define lid (rt<<1)
#define rid (rt<<1|1)
#define endl '\n'
#define pb push_back
using namespace std;
const int N = 2e5+5;
int dp[N],n;
int p[N],q[N];
int posq[N],posp[N];
vector <int> pos[N];
int c[N];
int lowbit(int x){return x&-x;}
int query(int x)
{int ans=0;if(x<=0)return 0;while(x){ans=max(ans,c[x]);x-=lowbit(x);}return ans;
}
void upd(int x,int val)
{if(x<=0)return ;while(x<=n){c[x]=max(c[x],val);x+=lowbit(x);}return;
}
int main()
{speed();// freopen("in.in","r",stdin);// freopen("out.out","w",stdout);cin>>n;for(int i=1;i<=n;i++)cin>>p[i],posp[p[i]]=i;for(int i=1;i<=n;i++)cin>>q[i],posq[q[i]]=i;for(int i=1;i<=n;i++){for(int j=i;j<=n;j+=i)if(posq[j])pos[i].pb(posq[j]);sort(pos[i].begin(),pos[i].end());reverse(pos[i].begin(),pos[i].end());}int ans=0;for(int i=1;i<=n;i++){int ls=0;for(auto v:pos[p[i]]){int j=v;// cout<<v<<endl;dp[j]=query(j);dp[j]=max(query(j-1)+1,dp[j]);ans=max(ans,dp[j]);// cout<<dp[i][j]<<endl;upd(j,dp[j]);}}cout<<ans<<endl;return 0;
}

image

两种写法,
回滚莫队(常熟略大)

点击查看代码
#include <bits/stdc++.h>
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define lid (rt<<1)
#define rid (rt<<1|1)
// #define endl '\n'
#define pb push_back
using namespace std;
const int N = 2e5+5,mod=1e9+7;
int x[N],n,m;
int sq,B,st[500],ed[500],b[N],cnt[N],ans[N],cc[N];
struct qu
{int l,r,id,bl;bool operator < (const qu& A)const{if(bl==A.bl)return r<A.r;return l<A.l;}
}q[N];
void init()
{sq=sqrt(n);B=n/sq;for(int i=1;i<=B;i++){st[i]=ed[i-1]+1;ed[i]=st[i]+sq-1;// cout<<st[i]<<" "<<ed[i]<<endl;}if(ed[B]<n){B++;st[B]=ed[B-1]+1;ed[B]=n;}
}
int RES;
void add(int d)
{cnt[x[d]]++;// cout<<cnt[x[d]]<<endl;RES=max(RES,cnt[x[d]]);// cout<<res<<endl;
}
void del(int d)
{cnt[x[d]]--;
}
int force(int l,int r)
{memset(cc,0,sizeof cc);int ans=0;for(int i=l;i<=r;i++)cc[x[i]]++,ans=max(ans,cc[x[i]]);return ans;
}
int main()
{speed();// freopen("T2.in","r",stdin);// freopen("in.in","r",stdin);// freopen("out.out","w",stdout);cin>>n>>m;for(int i=1;i<=n;i++){cin>>x[i];b[i]=x[i];}sort(b+1,b+1+n);int res=unique(b+1,b+1+n)-b-1;for(int i=1;i<=n;i++){x[i]=lower_bound(b+1,b+1+res,x[i])-b;// cout<<x[i]<<endl;}init();for(int i=1;i<=m;i++){cin>>q[i].l>>q[i].r;q[i].id=i;q[i].bl=(q[i].l-1)/sq+1;}sort(q+1,q+1+m);int j=1;int L,R;// sq=1e9;for(int i=1;i<=B&&j<=m;i++){L=ed[i]+1;R=ed[i];RES=0;memset(cnt,0,sizeof cnt);while(q[j].bl==i){if(q[j].r-q[j].l<=sq){ans[q[j].id]=force(q[j].l,q[j].r);j++;continue;}// cout<<L<<" "<<R<<" "<<q[j].l<<endl;L=ed[i]+1;while(R<q[j].r){++R;add(R);}// cout<<res<<endl;ll tmp=RES;while(L>q[j].l){L--;// cout<<L<<endl;add(L);}ans[q[j].id]=RES;// cout<<res<<endl;RES=tmp;while(L<=ed[i])del(L++);j++;}}for(int i=1;i<=m;i++)cout<<-ans[i]<<endl;return 0;
}

莫队

点击查看代码
#include <bits/stdc++.h>
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define lid (rt<<1)
#define rid (rt<<1|1)
#define endl '\n'
#define pb push_back
using namespace std;
const int N = 2e5+5;
int n,m,st[500],ed[500],sq,B,x[N],b[N],t[N],cnt[N],aa[N];
struct qu
{int l,r,id,bl;bool operator < (const qu& A)const{if(bl!=A.bl)return l<A.l;if(bl&1)return r<A.r;return r>A.r;}
}q[N];
void init()
{sq=sqrt(n);B=n/sq;for(int i=1;i<=B;i++){st[i]=ed[i-1]+1;ed[i]=st[i]+sq-1;}if(ed[B]<n){B++;st[B]=ed[B-1]+1;ed[B]=n;}
}
int ans;
inline void del(int x)
{if(ans==cnt[b[x]])ans--;t[cnt[b[x]]]--;if(t[cnt[b[x]]])ans=max(ans,cnt[b[x]]);cnt[b[x]]--;t[cnt[b[x]]]++;ans=max(ans,cnt[b[x]]);
}
inline void add(int x)
{t[cnt[b[x]]]--;cnt[b[x]]++;t[cnt[b[x]]]++;ans=max(ans,cnt[b[x]]);
}
int main()
{speed();// freopen("in.in","r",stdin);// freopen("out.out","w",stdout);cin>>n>>m;for(int i=1;i<=n;i++){cin>>x[i];b[i]=x[i];}sort(x+1,x+1+n);int res=unique(x+1,x+1+n)-x-1;for(int i=1;i<=n;i++){b[i]=lower_bound(x+1,x+1+res,b[i])-x;// cout<<x[i]<<endl;}init();for(int i=1;i<=m;i++){cin>>q[i].l>>q[i].r;q[i].id=i;q[i].bl=(q[i].l-1)/sq+1;}sort(q+1,q+1+m);int l=1,r=0;for(int i=1;i<=m;i++){while(l>q[i].l){add(--l);}while(l<q[i].l){del(l++);}while(r>q[i].r){del(r--);}while(r<q[i].r){add(++r);}aa[q[i].id]=ans;}for(int i=1;i<=m;i++)cout<<-aa[i]<<endl;return 0;
}

image

简单路径有两个义项,可以指图G(V,E)中路径上的顶点都不相同的路径,还可以指Rn中的弧,亦称简单弧,是曲线弧概念的推广。
所以说,一个子树中的简单路径,是不包含自身,不重复走且是可以横跨两个儿子的路径
暴力的话,我们可以得到性质:一条路可以回文,必须每个字母出现次数为偶数,最多有一个奇数,这时候可以二进制压缩一下,当一个状态为全是\(0\)或只有一个\(1\)时才合法,期望得分\(50pts\)

点击查看代码
#include <bits/stdc++.h>
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define lid (rt<<1)
#define rid (rt<<1|1)
#define endl '\n'
#define pb push_back
#define pii pair<int,int>
using namespace std;
const int N = 5e5+5;
int n,ans[N],fa[N];char val[N];
vector <int> edge[N];
map <int,int> len[N];
inline int get(int x)
{return 1<<(val[x]-'a');
}
inline void dfs(int u)
{len[u][0]=0;for(auto to:edge[u]){dfs(to);ans[u]=max(ans[to],ans[u]);for(auto v:len[to]){int zt=get(to)^v.first;if(len[u].find(zt)!=len[u].end())ans[u]=max(ans[u],len[u][zt]+v.second+1);if((zt^(zt&-zt))==0)ans[u]=max(ans[u],v.second+1);for(int j=0;j<22;j=-~j){if(len[u].find(zt^(1<<j))!=len[u].end())ans[u]=max(ans[u],len[u][zt^(1<<j)]+v.second+1);}}for(auto v:len[to])len[u][get(to)^v.first]=max(len[u][get(to)^v.first],v.second+1);}
}
int main()
{speed();// freopen("in.in","r",stdin);// freopen("out.out","w",stdout);cin>>n;for(int i=2;i<=n;i++){cin>>fa[i]>>val[i];edge[fa[i]].pb(i);}dfs(1);for(int i=1;i<=n;i++)cout<<ans[i]<<" ";return 0;
}

正解用到了启发式合并,我们先想最原始的暴力,我们可以计算\(x\)\(1\)路径上的异或状态,想求\(u,v\)之间,直接异或即可\(lca\)以上部分可以抵消掉,只有一条路径合法当且仅当二进制表示下只有一个\(1\)或全是\(0\)的时候,如果\(u,v\)合法(要么\(dis_u=dis_v和dis_udis_v只有1个1\)),那么产生的贡献为\(dep_u+dep_v-2dep_{lca}\),我们可以用一个数组\(book\)存储每个状态对应的深度,遍历其所有子树,然后对于一个状态\(dsu\)与其\(⊕\)得到结果合法的状态是固定的\(23\)种,于是我们只要检查\(book\)内有没有合法的即可,\(book\)首先存的是重链里面的状态,然后再与其他儿子中的状态合并,这也是启发式合并的意义所在,这也就从\(O(23n^2)\)优化到了\(O(23n\log n)\)

点击查看代码
#include <bits/stdc++.h>
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define lid (rt<<1)
#define rid (rt<<1|1)
#define endl '\n'
#define pb push_back
using namespace std;
const int N = 1e6+5;
int fa[N],L[N],R[N],rk[N],dfstot,sz[N],son[N],dis[N],dep[N],n;char val[N];
int ans[N],book[1<<22];//book表示当前路径状态对应的深度
vector <int> edge[N];
inline void dfs1(int u)
{dep[u]=dep[fa[u]]+1;sz[u]=1;L[u]=++dfstot;rk[dfstot]=u;//欧拉序,作用是方便遍历所有儿子for(auto to:edge[u]){dis[to]=dis[u]^(1<<(val[to]-'a'));//计算路径状态dfs1(to);sz[u]+=sz[to];if(sz[to]>sz[son[u]])son[u]=to;}R[u]=dfstot;
}
inline void dfs2(int u,bool heavy)
{for(auto to:edge[u]){if(to==son[u])continue;dfs2(to,0);ans[u]=max(ans[u],ans[to]);}if(son[u])dfs2(son[u],1),ans[u]=max(ans[u],ans[son[u]]);if(book[dis[u]])ans[u]=max(ans[u],book[dis[u]]-dep[u]);//更新答案for(int j=0;j<22;j++)if(book[dis[u]^(1<<j)])ans[u]=max(ans[u],book[dis[u]^(1<<j)]-dep[u]);//异或判断状态合法book[dis[u]]=max(book[dis[u]],dep[u]);//更新()别忘了for(auto to:edge[u]){if(to==son[u])continue;for(int j=L[to];j<=R[to];j++){int id=rk[j];if(book[dis[id]])ans[u]=max(ans[u],book[dis[id]]+dep[id]-2*dep[u]);for(int k=0;k<22;k++)if(book[dis[id]^(1<<k)])ans[u]=max(ans[u],book[dis[id]^(1<<k)]+dep[id]-2*dep[u]);}for(int j=L[to];j<=R[to];j++)book[dis[rk[j]]]=max(dep[rk[j]],book[dis[rk[j]]]);//计算完当前儿子分支,就可更新为下一个儿子做准备}if(!heavy)for(int j=L[u];j<=R[u];j++)book[dis[rk[j]]]=0;
}
int main()
{speed();// freopen("T3.in","r",stdin);// freopen("in.in","r",stdin);// freopen("out.out","w",stdout);cin>>n;for(int i=2;i<=n;i++){cin>>fa[i]>>val[i];edge[fa[i]].pb(i);}dfs1(1);dfs2(1,1);for(int i=1;i<=n;i++)	cout<<ans[i]<<" ";return 0;
}

T4https://www.luogu.com.cn/problem/AT_agc049_d

image

怎么说呢挂分变少了,有进步

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/779946.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

潜在新就业岗位超300万个 原生鸿蒙开发创造百万级人才缺口

在数字化转型的浪潮中,开发者作为数字经济的建设者和创新者,成为了推动社会进步的重要⼒量。InfoQ 研究中⼼最新发布的《中国开发者画像洞察研究报告2024》显示,截至2023年年底,中国泛开发者⼈数高达2067.21万,增速为2.5%。在这2000多万人中,鸿蒙⽣态吸引了超过254万开发…

python numpy

import numpy as np a=np.array([1,2,3,4]) b=np.array([5,6,7,8]) #相应项相乘再相加 print(np.inner(a,b)) #a的每一项乘以b的每一项组成新的矩阵 print(np.outer(a,b))

开发者洞察报告:百万级鸿蒙岗位缺口,开发者薪资涨幅43.1%

最近,极客邦科技双数研究院InfoQ研究中心《中国开发者画像洞察研究报告2024》正式发布,分析了开发者群体在数字经济浪潮中的新趋势与显著变化。根据《国资委79号文件》指示,2027年底,全部国央企必须完成信息化系统的信创改造。而HarmonyOS系统作为国产自研信创软件的代表,…

CH6 CH7

CH-6 时间与窗口 6.1 时间语义事件时间(Event Time):数据产生的时间,默认使用处理时间(Processing Time):数据到达窗口的时间摄入时间:被Flink Source读入的时间6.2 水位线 6.2.1 逻辑时钟 在使用事件时间时,Flink使用逻辑时钟对数据进行窗口计算。逻辑时钟依靠数据的时间…

CH2~CH5

一个Flink程序,就是对DataStream进行各种转换。基本上由以下几部分构成接下来分别从执行环境、数据源、转换操作、输出四大部分,介绍DataStream API。 导入Scala DataStream Api import org.apache.flink.streaming.api.scala._CH-5 DataStream API基础 一、执行环境 1.1 创建…

中国式报表搞不定?告诉你如何轻松解决

中国式报表,顾名思义,是一种在中国企业中广泛使用的报表格式。这种报表通常格式复杂、数据量大、数据层次多,涵盖了从基本数据到高层分析的各个层面。每一个字段都可能代表着不同的含义,每一列数据都有着深厚的背景,这让很多报表工具望而却步。然而,要想在中国企业中高效…

git的快速入门(含常用指令)

目录概念什么是gitgit与GitHub有什么区别提交、仓库、分支git的使用从GitHub上下载别人的代码直接将代码下载到本地克隆仓库获取代码将自己的代码上传到GitHub 本文拟将用通俗的语言描述git的使用方法,如有出入,请批评指正 概念 什么是git Git可以想象成一个超级高效的"…

最全MySQL面试20题和答案(二)

接第一期的MySQL面试二十题,这是之后的20题!索引百万级别或以上的数据如何删除? 关于索引:由于索引需要额外的维护成本,因为索引文件是单独存在的文件,所以当我们对数据的增加、修改、删除都会产生额外的对索引文件的操,这些操作需要消耗额外的IO,会降低增/改/删的执行…

Spring关于bean的一些基本知识

介绍了bean所需要关注的一些基本知识,掌握这些知识应该大体上可以满足信息应用开发在spring这座大厦中,去除掉最底部的核心(core)组件,那么最重要的无疑是bean和bean工厂。 剩余是AOP、设计模式,更之上的就是各种组件:DATA,WEBMVC...为了便于行文,这里把bean和bean工厂…

基于SiliconCloud快速体验GraphRag.Net

本文介绍了如何基于SiliconCloud快速体验GraphRag.Net。SiliconCloud介绍 SiliconCloud 基于优秀的开源基础模型,提供高性价比的 GenAI 服务。 不同于多数大模型云服务平台只提供自家大模型 API,SiliconCloud上架了包括 Qwen、DeepSeek、GLM、Yi、Mistral、LLaMA 3、SDXL、In…

金蝶云星空单据体数量汇总-分组列信息

金蝶云星空单据体数量汇总-分组列信息 bos配置 效果展示

成品库存周转率报表(二)

成品库存周转率报表(二)一、报表逻辑 组织=供应链中心,仓库=成品仓,区间可选,可单独搜索某物料,物料基础数据为使用组织=供应链中心,仓库=成品仓作为底表(1)库存数取自《库存账龄分析表》或《库存汇总查询》-历史查询(2)期初库存为起始日期的查询库存 期末库存为结束…