首页 > 其他分享 >多校A层冲刺NOIP2024模拟赛26 && G

多校A层冲刺NOIP2024模拟赛26 && G

时间:2024-11-27 17:12:30浏览次数:7  
标签:26 int ll 多校 long 然后 && sum define

多校A层冲刺NOIP2024模拟赛26 && G

T1 随机游走

考虑到达一个点后,我们该往他的那个儿子走,简单膜一下只有两个儿子的样例后发现条件是 $ \frac{w_i}{v_i} $ 越小越优先,其中 $ w_i $ 表示他到父亲的边权, $ v_i $ 表示他的点权,然后尝试推广,膜个稍微大点的样例发现完全是通用的,此时 $ w_i $ 表示 $ i $ 的子树里所有的点到父亲的边权总和, $ v_i $ 表示 $ i $ 子树里所有的点权和。然后排序再算贡献就行了。

T2 分发奖励

还真是没想到场上读了将近一个小时的题面都没读明白他要干什么,竟然被阅读理解 hack 了,然后这题直接没写。

大概题意是说,有一棵树和 q 次操作,每次选择两个点(可能相同)然后给他们的子树里面的点全部带上一种属性,然后进行完这些操作之后对于每个点 $ i $ 求出有多少个点满足和 $ i $ 有任何一种相同属性。

其实很简单,我们直接把操作都挂在点上后直接 $ dfs $ ,每次到了一个点,就把他挂着的那些操作加上去, $ dfs $ 完了回溯时就直接撤销贡献。但是这不是一个区间加,而是一个区间覆盖,然后这就导致撤销操作很难完成,但是我们注意到区间覆盖时分成每一个小段后,这个区间的 $ sum_k $ 必定等于 $ r-l+1 $ ,所以我们每次记 $ tag_k $ 表示他被直接覆盖了几次,那么撤销时直接 $ --tag_k $ ,如果 $ tag_k $ 不为 0 的话, $ sum_k $ 还是 $ r-l+1 $ ,否则 $ sum_k $ 在 $ k $ 本层没有贡献,所以 $ sum_k = sum_{ls(k)} + sum_{rs(k)} $ ,然后直接做就行了。

给个码
/*
GGrun
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int ll
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define fi first
#define se second
#define ps push_back
#define mk make_pair
const int N=1e6+10,inf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f,mod=1e9+7;
inline ll read(){
	char c=getchar();ll x=0;bool f=0;
	while(!isdigit(c))f=c=='-'?1:0,c=getchar();
	while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return f?-x:x;
}
int n,q,a[N],b[N],fa[N],dfn[N],ed[N],cnt,sz[N];
vector<int> son[N];
inline void dfs(int x){
	dfn[x]=++cnt;sz[x]=1;
	for(auto j:son[x]){
		dfs(j);sz[x]+=sz[j];
	}
	ed[x]=cnt;
}
int tot,now,ans[N],sum[N<<2],tag[N<<2];
vector<int> v[N];
vector<int> op[N];
inline void add(int k,int l,int r,int L,int R,int v){
	if(L<=l&&r<=R){
		if(v==0){
			if(!--tag[k]){
				if(l!=r)sum[k]=sum[k<<1]+sum[k<<1|1];
				else sum[k]=0;
			}
		}
		else ++tag[k],sum[k]=r-l+1;
		return;
	}
	int mid=l+r>>1;
	if(L<=mid)add(k<<1,l,mid,L,R,v);
	if(R>mid)add(k<<1|1,mid+1,r,L,R,v);
	if(!tag[k])sum[k]=sum[k<<1]+sum[k<<1|1];
}
inline int ask(int k,int l,int r,int pos){
	if(tag[k]||l==r)return sum[k];
	int mid=l+r>>1;
	return pos<=mid?ask(k<<1,l,mid,pos):ask(k<<1|1,mid+1,r,pos);
}
inline void sol(int x){
	vector<int> qu;
	bool zh=0;
	for(auto i:v[x]){
		if(!tot){
			++tot,add(1,1,n,dfn[x],ed[x],1),zh=1;
			// cout<<x<<' '<<i<<' '<<sum[1]<<"ADD1\n";
		}
		if(!ask(1,1,n,dfn[i])){
			add(1,1,n,dfn[i],ed[i],1),qu.ps(i);
			// cout<<x<<' '<<i<<' '<<sum[1]<<"ADD2\n";
		}
	}
	// cout<<x<<' '<<sum[1]<<endl;
	ans[x]=max(0ll,sum[1]-1);
	for(auto i:son[x])
		sol(i);
	for(auto i:qu){
		add(1,1,n,dfn[i],ed[i],0);
		// cout<<x<<' '<<i<<' '<<sum[1]<<"SHAN2\n";
	}
	if(zh){
		--tot,add(1,1,n,dfn[x],ed[x],0),zh=0;
		// cout<<x<<' '<<sum[1]<<"SHAN1\n";
	}
}
signed main(){
	freopen("reward.in","r",stdin);
	freopen("reward.out","w",stdout);
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	n=read(),q=read();
	for(int i=2;i<=n;++i)
		fa[i]=read(),son[fa[i]].ps(i);
	dfs(1);
	for(int i=1;i<=q;++i){
		a[i]=read(),b[i]=read();
		v[a[i]].ps(b[i]);v[b[i]].ps(a[i]);
	}
	sol(1);
	for(int i=1;i<=n;++i)
		cout<<ans[i]<<' ';
}

T3 卡路里

看了半天 T2 题面无果后先做了 T3。

首先肯定会 $ O(m^2 n) $ 的暴力枚举对吧,发现每次 $ O(n) $ 遍历去求贡献很唐,然后我们看看能不能优化一下,然后要想每次知道 所有奶茶的最大值无法优化,最少也得 $ O(n) $ 遍历一下,但是我们只关心他们的和,所以我们把填表改为刷表,也就是说,我们对于每个 $ a_{i,j} $ 去看他能贡献给那些区间,然后很容易想到对于每一款奶茶,拿单调栈 $ O(m) $ 的跑一下前面第一个大于等于他的,和后面第一个大于他的位置 (等于的情况放在哪边都无所谓,但必须放一边),然后设他的前驱是 $ l_j $ ,后继是 $ r_j $ ,那么 $ a_{i,j} $ 可以贡献的区间就是 左端点是 $ [ l_j , j ] $ ,右端点是 $ [ j , r_j ] $ 的区间,然后这是一个矩形加,直接上差分扫描线,树状数组维护,然后时间复杂度降为 $ O(m^2 \log(m)) $ ,标算 3e8 ,如果你算一个枚举区间时 $ \dfrac{1}{2} $ 的常数的话没准能卡过去。但是我们又发现这个树状数组也很唐,反正我们都要 $ O(m^2) $ 枚举区间了,为什么不每次直接暴力扫过去维护前缀和,然后把树状数组的 $ \log(m) $ 拿掉即可做到 $ O(m^2) $ 。

然后好像还有个 $ O(mn \log(m)) $ 的做法,大概就是直接把那个 $ d_i $ 值扔到线段树里,每次确定左端点后直接把扫描线的贡献都加进去,然后直接查最大值即可,标算比 $ O(m^2) $ 快,但实际上常数比 $ O(m^2) $ 大。

给个码
/*
GGrun
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int ll
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define fi first
#define se second
#define ps push_back
#define mk make_pair
const int N=1e6+10,inf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f,mod=1e9+7;
inline ll read(){
	char c=getchar();ll x=0;bool f=0;
	while(!isdigit(c))f=c=='-'?1:0,c=getchar();
	while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return f?-x:x;
}
bool f1;
int n,m,a[5050][210];
ll d[5050];
int q[10000],top,zuo[5050],you[5050];
vector<pair<pii,int> > v[5050];
ll pre[5050],jia[5050];
bool f2;
signed main(){
	freopen("calorie.in","r",stdin);
	freopen("calorie.out","w",stdout);
	// cout<<(&f1-&f2)/1024/1024<<endl;
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	n=read(),m=read();
	for(int i=1;i<m;++i)
		d[i]=read()+d[i-1];
	for(int i=1;i<=m;++i){
		for(int j=1;j<=n;++j){
			a[i][j]=read();
		}
	}
	for(int i=1;i<=n;++i){
		q[top=0]=0;
		a[0][i]=a[m+1][i]=inf;
		for(int j=1;j<=m+1;++j){
			while(top&&a[q[top]][i]<a[j][i])you[q[top--]]=j;
			zuo[j]=q[top];q[++top]=j;
		}
		for(int j=1;j<=m;++j){
			// cout<<i<<' '<<j<<' '<<zuo[j]<<' '<<you[j]<<endl;
			v[zuo[j]+1].ps({{j,you[j]-1},a[j][i]}),v[j+1].ps({{j,you[j]-1},-a[j][i]});
		}
	}
	ll ans=0;
	for(int i=1;i<=m;++i){
		for(int j=0;j<=m;++j)
			jia[j]=0;
		for(auto j:v[i]){
			jia[j.fi.fi]+=j.se;jia[j.fi.se+1]-=j.se;
		}
		ll now=0;
		for(int j=0;j<i;++j)
			now+=jia[j],pre[j]+=now;
		for(int j=i;j<=m;++j){
			now+=jia[j];
			pre[j]+=now;
			// cout<<i<<' '<<j<<' '<<pre[j]<<endl;
			ans=max(ans,pre[j]-(d[j-1]-d[i-1]));
		}
	}
	cout<<ans<<'\n';
}

T4 传话游戏

目前只会 32pts 的部分分(场上还打挂了)。

run(

G

这几天感觉挺唐的,自从 NOIP24 那场暴力没打好之后状态一直不好,赛时有很多分没拿到,而且确实感觉到旁边的人实力强大。

NOIP24:其实那场可以拿到 rk1 的分,但是 T2 40pts 的部分分没拿上,因为当时感觉切了两道题之后虽然还在打,但是少了点兴奋劲。

NOIP25:T2 n,m 写反了挂了 100pts, T4 赛时没怎么看,但其实是比较简单的线段树板子,大概T2对拍过了之后效率就极低了,当时 T2 是 10:11 交的,要是不挂还是首A呢,后面着两个小时相当于只拿了 10 pts。

梦熊那场没挂,但是会的比较少。

加赛7 其实拼满暴力也是 305pts,但是 T3挂了, T4着急打正解,正解没打出来,暴力也没打好。


然后就是这场,T2没读明白题面,T4暴力挂了 28 pts。


总的来说就是过了一些题之后紧张度就下降了,然后效率极低,基本上2个小时之后得分率就大大降低了,上次 csp-s 也是,三个小时切了三题之后半个小时没打出 T4暴力,其实并没有说半场开香槟,但是内心里已经不再那么紧张了,导致效率降低,以后会给自己多一些适当的压力,提高考试时的效率,争取调整到当时一开始集训时的状态。


反正已经走到这了,那就今天下NOIP绝命书吧,但凡这次发挥正常,省选的时候我一定能拼进省队




标签:26,int,ll,多校,long,然后,&&,sum,define
From: https://www.cnblogs.com/GGrun-sum/p/18572666

相关文章

  • 985研一学习日记 - 2024.11.26
    一个人内耗,说明他活在过去;一个人焦虑,说明他活在未来。只有当一个人平静时,他才活在现在。日常1、起床6:002、健身1.5h3、LeetCode刷了0题今天没刷题,这几天应该都不咋会刷题了4、复盘22:30不复盘等于白学!!!学习和感想JUC并发编程1.JUC线程池概述和架构通过线程池......
  • 【快慢指针技巧】:高效解决链表和数组问题(26,83,27)
    ......
  • SpringBoot枣阳市第二人民医院信息管理系统73263 程序+源码+数据库+调试部署+开发环境
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表系统内容;医院管理员,医生,线上挂号,用户,门诊病历,药品信息,就医记录开题报告内容项目名称:SpringBoot枣阳市第二人民医院信息管理系统项目编号:73263一、项......
  • pikachu文件上传_2024-11-26
    什么是文件上传漏洞文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像、上传附件等等。当用户点击上传按钮后,后台会对上传的文件进行判断比如是否是指定的类型、后缀名、大小等等,然后将其按照设计的格式进行重命名后存储在指定的目录。如果说后台对上传的文......
  • 【2024-11-26】跑步时在想
    20:00必须敢于正视,这才可望敢想、敢说、敢做、敢当。                                                 ——XX我觉得上天一定是眷顾着我的,昨晚下班回到小区附近时,没下......
  • springboot 露营吧户外活动交流社区小程序-毕业设计源码92606
    “露营吧”户外活动交流社区小程序的设计与开发摘 要本研究旨在设计并开发名为“露营吧”的户外活动交流社区小程序。随着户外活动在现代生活中的重要性不断提升,这款小程序旨在为户外爱好者提供一个互动交流的平台。通过整合社交功能、活动发布、安全装备等特色模块,用户可......
  • 2024.11.26 周二日常
    2024.11.26周二日常Q1.1200给定一数组k(代表n个人的倍率),设在每个人上投资为xi,若其胜利则获k*xi,最终一人胜利。问是否可以保证无论谁胜利,收益大于总投资的方案。(n<=20,k<=50)Q2.1300给定一数组,问最小的k使所有长度为k的区间按位或相等。Q3.1500给定一数组,定......
  • HCIA基础02课后习题1126
    问题1:普通用户:        例如有一个名为user1的普通用户,当user1登录系统后在命令行中输入cd~,就会进入到/home/user1目录(通常情况下,普通用户的主目录在/home目录下,目录名和用户名相同)。root用户(超级用户):        当以root身份登录系统,在命令行输......
  • 2024.11.26
    要修改表中的主键字段名称,你需要执行以下步骤:删除现有的主键约束。修改字段名称。重新添加主键约束。以下是针对你的需求,对tb_task_assignment表进行修改的SQL语句:步骤1:删除现有的主键约束首先,你需要删除现有的主键约束。这通常涉及到查询数据库的元数据来找到主键约束......
  • 2024.11.26
    今日总结上午打南外的比赛,只会做第一题的Dp第二题的数位Dp差一点就想出来了,第三题打暴力挂了,第四题不会,下午吃饭前改完了第二题,晚上做了今天没有写的二本的比赛的前两题1:团子制作这道题是Dp加搜索的结合,需要一边搜索,一边进行Dp转移,一定要处理好边界问题,转移时要注意是二维转移......