暑假集训CSP提高模拟16
1.九次九日九重色
一开始做的时候被题面给迷惑住了,没想到可以跳着 匹配(样例太水)。
那我们来考虑如何做,首先思路肯定是把能匹配的暴力求出来,根据不知道怎么搞的调和计数,这样的复杂度还不是很高,是
观察一下预处理出来的序列,是不是很熟悉。没错剩下的就是求最长上升子序列。
那求最长上升子序列有两种方法,一个是
这里主要了解后面的(因为赛时我还不会)。
原理其实比较简单,看代码就能看懂。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+107;
int n,x[N],y[N];
int pos1[N],pos2[N];
struct lmy
{
int x,y;
}s[N<<5];
bool comp(lmy a,lmy b)
{
if(a.x==b.x) return a.y>b.y;
return a.x<b.x;
}
int st[N<<5],top;
int cnt;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&x[i]),pos1[x[i]]=i;
for(int i=1;i<=n;i++) scanf("%d",&y[i]),pos2[y[i]]=i;
for(int i=1;i<=n;i++)
{
for(int j=1;j*x[i]<=n;j++)
{
s[++cnt]={pos1[x[i]],pos2[x[i]*j]};
}
}
sort(s+1,s+1+cnt,comp);
for(int i=1;i<=cnt;i++)
{
if(st[top]<s[i].y)
{
st[++top]=s[i].y;
}
else
{
st[lower_bound(st+1,st+top+1,s[i].y)-st]=s[i].y;
}
}
printf("%d",top);
}
2.天色天歌天籁音
简单理解一下题意,再自己手模一下,可以发现题目所求的是区间众数,然后它强调了一下各个互不影响,可以考虑莫队(其实挺套路的,但我不会莫队了,大悲)。
主要讲讲add和del的操作,
首先add比较好说,只需要直接计数。
del就需要分讨一下。
1.减之前比目前最大众数小,无影响。
2.本身是最大众数,减完之后还是,无影响。
3.本身为最大众数(但众数有很多个),减之后不为最大众数(主要的问题)。
关于这个问题,我们就可以开一个桶来记录每个数出现个数(众数)的个数(是有点绕,得理解一下),到这这个题就没什么了
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+107;
int n,m,a[N];
int li[N],ri[N],bg[N],tot;
struct lmy
{
int x,y,id;
}q[N];
bool comp(lmy &a,lmy &b)
{
int p=bg[a.x],q=bg[b.x];
if(p!=q) return p<q;
if(p&1) return a.y<b.y;
else return a.y>b.y;
}
void fk()
{
int sq=sqrt(n);
for(int i=1;i<=sq;i++)
{
li[i]=ri[i-1]+1;
ri[i]=sq*i;
if(i==sq) ri[i]=n;
for(int j=li[i];j<=ri[i];j++) bg[j]=i;
}
}
map<int,int> mp;
int sum,t[N],cnt[N],ans[N];
void add(int i)
{
t[cnt[a[i]]]--;
t[++cnt[a[i]]]++;
sum=max(sum,cnt[a[i]]);
}
void del(int i)
{
t[cnt[a[i]]]--;
if(cnt[a[i]]==sum&&!t[cnt[a[i]]]) sum--;
t[--cnt[a[i]]]++;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(mp.find(a[i])==mp.end())
{
mp[a[i]]=++tot;
}
a[i]=mp[a[i]];
}
fk();
for(int i=1;i<=m;i++)
{
int l,r;
scanf("%d%d",&l,&r);
q[i]={l,r,i};
}
sort(q+1,q+1+m,comp);
int l=1,r=0;
for(int i=1;i<=m;i++)
{
while(r<q[i].y) add(++r);
while(r>q[i].y) del(r--);
while(l<q[i].x) del(l++);
while(l>q[i].x) add(--l);
ans[q[i].id]=sum;
}
for(int i=1;i<=m;i++) printf("%d\n",-ans[i]);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话