首页 > 其他分享 >CSP2024 前集训:csp-s模拟11

CSP2024 前集训:csp-s模拟11

时间:2024-10-16 10:59:24浏览次数:1  
标签:11 unlocked int lim void CSP2024 Tp read csp

前言

image

T1 挂了,后面几道赛时都不那么可做,T2 读假题了浪费太多时间,T3 没调出来。

T4 是原,但是整个机房只有一个人当时改了,所以还是没人写,因为 T4 是原,还加了个 T5,也不太可做。

T1 玩水

对于一个点 \((i,j)\),若 \(s_{i+1,j}=s_{i,j+1}\) 则称其为分点,若一个分店后面还有分点或两个分点相邻则有解,二维前缀和维护即可。

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=1010;
template<typename Tp> inline void read(Tp&x)
{
	x=0;register bool z=true;
	register char c=getchar_unlocked();
	for(;!isdigit(c);c=getchar_unlocked()) if(c=='-') z=0;
	for(;isdigit(c);c=getchar_unlocked()) x=(x<<1)+(x<<3)+(c^48);
	x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar_unlocked((x%10)+'0');}
template<typename Tp> inline void write(Tp x){if(x<0)putchar_unlocked('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar_unlocked(' ');write(y...);}
int T,n,m,ans,sum[N][N]; char s[N][N]; bitset<N>spl[N];
int calc(int x1,int y1,int x2,int y2) 
{return x1--,y1--,sum[x2][y2]-sum[x1][y2]-sum[x2][y1]+sum[x1][y1];}
signed main()
{
	freopen("water.in","r",stdin),freopen("water.out","w",stdout);
	for(read(T);T;T--,ans=0,memset(sum,0,sizeof(sum)))
	{
		read(n,m); for(int i=1;i<=n;i++) spl[i].reset();
		for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
			for(s[i][j]=getchar_unlocked();s[i][j]<'a'||s[i][j]>'z';s[i][j]=getchar_unlocked());
		for(int i=1;i<=n-1;i++) for(int j=1;j<=m-1;j++)
			if(s[i][j+1]==s[i+1][j]) spl[i][j]=1;
		for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
			sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+spl[i][j];
		for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
			if((spl[i][j]&&spl[i][j+1])||(spl[i][j]&&spl[i+1][j])||(spl[i-1][j-1]&&calc(i,j,n,m)))
			{ans=1; break;}
		write(ans),puts("");
	}
}

T2 AVL 树

中序遍历最小等价于前序遍历最小,因为一个点选了他的父亲必选。

那么贪心,若当前点为其父亲的左二子,则计算出其右儿子最少需要多少节点,若计算出的 \(\le k\) 就保留当前点即可。

具体实现挺屎的不想说了,统计最小最大深度,找一下规律维护。

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=5e5+10;
template<typename Tp> inline void read(Tp&x)
{
	x=0;register bool z=true;
	register char c=getchar_unlocked();
	for(;!isdigit(c);c=getchar_unlocked()) if(c=='-') z=0;
	for(;isdigit(c);c=getchar_unlocked()) x=(x<<1)+(x<<3)+(c^48);
	x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar_unlocked((x%10)+'0');}
template<typename Tp> inline void write(Tp x){if(x<0)putchar_unlocked('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar_unlocked(' ');write(y...);}
int n,m,rt,sum,f[30],h[N],fa[N],ls[N],rs[N],dep[N],lim[N],used[N]; bitset<N>ans;
void dfs(int x)
{
	if(!x) return ; h[x]=dep[x]=dep[fa[x]]+1;
	dfs(ls[x]),dfs(rs[x]),h[x]=max({h[x],h[ls[x]],h[rs[x]]});
}
bool check(int x)
{
	sum=lim[0]=0; for(int i=x;i;sum+=!ans[i],i=fa[i]) if(ls[fa[i]]==i)
		sum+=f[max({used[fa[i]]-1,dep[x]-1,lim[rs[fa[i]]]})-dep[fa[i]]];
	return sum<=m;
}
void insert(int x)
{
	used[x]=max(used[x],dep[x]); for(int i=x,tmp;i;i=fa[i])
	{
		m-=!ans[i],ans.set(i),used[fa[i]]=max(used[fa[i]],dep[x]);
		if(ls[fa[i]]==i&&(tmp=rs[fa[i]])) lim[tmp]=max(lim[tmp],used[fa[i]]-1);
	}
}
void solve(int x)
{
	if(!x) return ; if(check(x)) insert(x);
	if(!ls[x]||!rs[x]) lim[ls[x]+rs[x]]=max(lim[ls[x]+rs[x]],lim[x]);
	else if(h[ls[x]]>=lim[x])
		lim[ls[x]]=max(lim[ls[x]],lim[x]),lim[rs[x]]=max(lim[rs[x]],lim[x]-1);
	else lim[ls[x]]=max(lim[ls[x]],lim[x]-1),lim[rs[x]]=max(lim[rs[x]],lim[x]);
	solve(ls[x]),solve(rs[x]);
}
signed main()
{
	freopen("avl.in","r",stdin),freopen("avl.out","w",stdout);
	read(n,m); for(int i=1;i<=n;i++) 
		read(fa[i]),fa[i]==-1?fa[rt=i]=0:(i<fa[i]?ls[fa[i]]=i:rs[fa[i]]=i);
	dfs(rt); f[1]=1; for(int i=2;i<=h[rt];i++) f[i]=f[i-1]+f[i-2]+1;
	solve(rt); for(int i=1;i<=n;i++) write(ans[i]);
}

T3 暴雨

水到处流很烦,考虑用一个最高的土地将两边分开,这样只会往一遍流了,这样枚举这个最高的土地已经 \(O(k)\) 了。

然后直接 DP 转移,\(f_{i,j,k,0/1}\) 表示到了第 \(i\) 个土地、最大值位置为 \(j\)、铲了 \(k\) 块、奇偶性时的方案数,直接转移即可,考虑铲 \(k\) 次做多产生 \(k+1\) 个最大值,由此一次 DP 复杂度为 \(O(nk^2)\)。

两遍正序(倒序)各跑一遍合并即可,

细节上,发现 \(j\) 时间是 \(O(k)\),但空间开了 \(O(n)\) (因为这样好写)会炸,所以 \(i\) 这一维滚一下即可;同时枚举过的最大值视为已经铲掉,不能再铲。

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define sort stable_sort
#define mkp make_pair
#define se second
using namespace std;
const int N=25010,M=30,P=1e9+7;
template<typename Tp> inline void read(Tp&x)
{
	x=0;register bool z=true;
	register char c=getchar_unlocked();
	for(;!isdigit(c);c=getchar_unlocked()) if(c=='-') z=0;
	for(;isdigit(c);c=getchar_unlocked()) x=(x<<1)+(x<<3)+(c^48);
	x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar_unlocked((x%10)+'0');}
template<typename Tp> inline void write(Tp x){if(x<0)putchar_unlocked('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar_unlocked(' ');write(y...);}
int n,m,ans,a[N],id[N],mx[N][M],cnt1[M][2],cnt2[M][2],f[2][N][M][2];
set<pair<int,int> >s;
void dp(int len,int maxx)
{
	reverse(a+1,a+1+n),s.clear();
	memset(f,0,sizeof(f)),f[0][0][0][0]=f[1][1][0][0]=1,f[1][0][1][0]=!!a[1];
	for(int i=1,j;i<=len;mx[i][++j]=0,i++)
	{
		for(s.insert(mkp(a[i],i)),j=0;s.size()>maxx+2;s.erase(s.begin()));
		for(auto it=s.begin();it!=s.end();it++) mx[i][++j]=it->se;
	}
	for(int i=2,x=0,y=1;i<=len;i++,x^=1,y^=1)
	{
		memset(f[x][i],0,sizeof(f[x][i])); for(int j=1,h;j<=maxx+2&&mx[i][j-1];j++)
		{
			if((h=mx[i][j])==i) continue; bool tmp; memset(f[x][h],0,sizeof(f[x][h]));
			for(int k=0;k<=min(i,maxx);k++)
			{
				if(a[i]>=a[h]) (f[x][i][k][0]+=f[y][h][k][0])%=P,(f[x][i][k][1]+=f[y][h][k][1])%=P;
				else f[x][h][k][0]=f[y][h][k][tmp=(a[h]-a[i])&1],f[x][h][k][1]=f[y][h][k][!tmp];
				if(k>0&&a[i]) (f[x][h][k][0]+=f[y][h][k-1][tmp=a[h]&1])%=P,(f[x][h][k][1]+=f[y][h][k-1][!tmp])%=P;
			}
		}
	}
}
signed main()
{
	freopen("rain.in","r",stdin),freopen("rain.out","w",stdout);
	read(n,m); for(int i=1;i<=n;i++) read(a[i]),id[i]=i,mx[i][0]=-1; mx[0][0]=-1;
	sort(id+1,id+1+n,[](int x,int y){return a[x]>a[y];}); reverse(a+1,a+1+n);
	for(int o=m,now;~o;a[n-now+1]=0,o--)
	{
		now=id[m-o+1],memset(cnt1,0,sizeof(cnt1)),memset(cnt2,0,sizeof(cnt2));
		dp(now-1,min(now-1,o));
		for(int i=0;i<=min(now-1,o);i++) 
			for(int j=1;j<=min(now-1,o)+2&&mx[now-1][j-1];j++)
			{
				(cnt1[i][0]+=f[(now-1)&1][mx[now-1][j]][i][0])%=P;
				(cnt1[i][1]+=f[(now-1)&1][mx[now-1][j]][i][1])%=P;
			}
		dp(n-now,min(n-now,o));
		for(int i=0;i<=min(n-now,o);i++) 
			for(int j=1;j<=min(n-now,o)+2&&mx[n-now][j-1];j++)
			{
				(cnt2[i][0]+=f[(n-now)&1][mx[n-now][j]][i][0])%=P;
				(cnt2[i][1]+=f[(n-now)&1][mx[n-now][j]][i][1])%=P;
			}
		for(int i=0;i<=min(now-1,o);i++) (ans+=(1ll*cnt1[i][0]*cnt2[o-i][0]%P+1ll*cnt1[i][1]*cnt2[o-i][1]%P)%P)%=P;
	}
	write(ans);
}

T4 置换

抽象题,看 Pursuing_OIer 的博吧。

T5 传统题

懒得改,咕了咕了。

标签:11,unlocked,int,lim,void,CSP2024,Tp,read,csp
From: https://www.cnblogs.com/Charlieljk/p/18469408

相关文章

  • YOLOv11性能评估指标 AP、mAP、Precision、Recall、FPS、IoU、混淆矩阵、F1等YOLO相关
    开始讲解之前推荐一下我的专栏,本专栏的内容支持(分类、检测、分割、追踪、关键点检测),专栏目前为限时折扣,欢迎大家订阅本专栏,本专栏每周更新3-5篇最新机制,更有包含我所有改进的文件和交流群提供给大家。 专栏回顾:YOLOv11改进系列专栏——本专栏持续复习各种顶会内容——科......
  • YOLOv11改进 | 代码逐行解析(一) | 项目目录构造分析
     一、本文介绍Hello,大家好这次给大家带来的不是改进,是整个YOLOv11项目的分析,整个系列大概会更新5-7篇左右的文章,从项目的目录到每一个功能代码的都会进行详细的讲解,下面开始进行YOLOv11逐行解析的第一篇——项目目录构造分析开头之前顺便给大家推荐一下我的专栏,本专栏更新上......
  • [2023 CSP-J]题目思考与反思
    小Y的桌子上放着\(n\)个苹果从左到右排成一列,编号为从\(1\)到\(n\\\)。小苞是小Y的好朋友,每天她都会从中拿走一些苹果。\(\\\)每天在拿的时候,小苞都是从左侧第\(1\)个苹果开始、每隔\(2\)个苹果拿走\(1\)个苹果。随后小苞会将剩下的苹果按原先的顺序重新排成一......
  • [题解]CF1136E Nastya Hasn't Written a Legend
    思路首先考虑操作1一个点\(i\)能被操作到的条件。注意到此时\(x\simi-1\)这些位置都是被更新过的,再仔细观察此时\(\forallj\in[x,i),a_j=a_x+\sum_{p=x}^{j-1}k_p\)。那么对于\(a_i\)如果会被修改将会变为\(a_x+\sum_{p=x}^{i-1}k_p\),那么\(a_i......
  • 代码随想录算法训练营day16| 513.找树左下角的值 112.路径总和 106.从中序和后序
    学习资料:https://programmercarl.com/0513.找树左下角的值.html#算法公开课递归、回溯返回值:True/False,root构建二叉树TrueNode(root_value)513.找树左下角的值(实例变量self.result,self.maxdepth;找到叶子节点,若深度>self.maxdepth,则更新最大深度;只考虑左和右子树,用递归+......
  • 【人工智能/计算机工程/大数据】第五届人工智能与计算工程国际学术会议(ICAICE 2024,202
    The5thInternationalConferenceonArtificialIntelligenceandComputerEngineering第五届人工智能与计算工程国际学术会议(ICAICE2024)会议官网:www.event-icaice.orgThe5thInternationalConferenceonArtificialIntelligenceandComputerEngineer......
  • springboot校园资产管理(11725)
     有需要的同学,源代码和配套文档领取,加文章最下方的名片哦一、项目演示项目演示视频二、资料介绍完整源代码(前后端源代码+SQL脚本)配套文档(LW+PPT+开题报告)远程调试控屏包运行三、技术介绍Java语言SSM框架SpringBoot框架Vue框架JSP页面Mysql数据库IDEA/Eclipse开发四、项......
  • springboot大学生科创项目在线管理系统(11744)
     有需要的同学,源代码和配套文档领取,加文章最下方的名片哦一、项目演示项目演示视频二、资料介绍完整源代码(前后端源代码+SQL脚本)配套文档(LW+PPT+开题报告)远程调试控屏包运行三、技术介绍Java语言SSM框架SpringBoot框架Vue框架JSP页面Mysql数据库IDEA/Eclipse开发四、项......
  • Win11经常自动弹出任务栏怎么办
    Win11经常自动弹出任务栏怎么办?我们有时候在使用Win11系统的电脑玩游戏的时候会经常碰到任务栏自动弹出来,这样不仅会大大的影响游戏的体验感,还影响电脑的使用,那么我们遇到这种情况要怎么办呢?下面就和小编一起来看看有什么解决方法吧。Win11自动弹出任务栏的解决方法方法......
  • Win11如何设置双声道音效-Win11双声道音效的设置方法
    有一些用户在使用Windows11操作系统时,可能会希望调整音频设置以获得更好的听觉体验。其实双声道音效是一种常见的音频配置,它可以提供更加立体和丰富的音响效果。如果您想要在Windows11中设置双声道音效,以下是一些简单的步骤指导,一起看看吧。Win11双声道音效的设置方法......