首页 > 其他分享 >CSP提高组模拟1

CSP提高组模拟1

时间:2024-07-12 21:07:39浏览次数:14  
标签:rt int 提高 tr tp long ans CSP 模拟

T1

很明显的最短路floyed算法,但是这个最大的点权却不是很好维护,但我们可以想到枚举最大的点权其实就可以相当于枚举floyed中的k,那么这时我们要对k进行一个排序操作,使得我们每次枚举的中转点k为枚举经过路径的点权最大的点从而达到同时走最短路并维护点权最大值。

点击查看代码
#include<bits/stdc++.h>
using namespace std;

#define int long long
const int N=400;
int n,m,q;

struct lmy
{
	int id,w;
}pos[N];
int rk[N];
int dis[N][N],ans[N][N];

bool comp(lmy a,lmy b)
{
	return a.w<b.w;
}
signed main()
{
//	freopen("path.in","r",stdin);
//	freopen("path.out","w",stdout); 
	scanf("%lld%lld%lld",&n,&m,&q);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&pos[i].w);
		pos[i].id=i;
	}
	sort(pos+1,pos+1+n,comp);
	for(int i=1;i<=n;i++)
	{
		rk[pos[i].id]=i;
	}
	memset(dis,0x3f,sizeof dis);
	for(int i=1;i<=n;i++)
	{
		dis[i][i]=0;
	}
	for(int i=1;i<=m;i++)
	{
		int x,y,dt;
		scanf("%lld%lld%lld",&x,&y,&dt);
		dis[rk[x]][rk[y]]=min(dis[rk[x]][rk[y]],dt);
		dis[rk[y]][rk[x]]=min(dis[rk[y]][rk[x]],dt);
	}
	memset(ans,0x3f,sizeof ans);
	for(int k=1;k<=n;k++)
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(i==j) continue;
                dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
                if(dis[i][j]==dis[i][k]+dis[k][j]) 
                    ans[i][j]=min(ans[i][j],dis[i][j]+max({pos[i].w,pos[j].w,pos[k].w}));
			}
		}
	}
	for(int i=1;i<=q;i++)
	{
		int s,t;
		scanf("%lld%lld",&s,&t);
		if(ans[rk[s]][rk[t]]>=0x3f3f3f3f3f3f3f3f) printf("-1\n");
		else printf("%lld\n",ans[rk[s]][rk[t]]);
	}
}
##T2

首先就是可以想到维护一个二维前缀和。
然后像这种具有单调性的数列(只维护正整数的前缀和)维护我们可以想到用单调队列。
那我们就可以一行一行的删去看是否符合条件,
最后剩下的我们就一点一点凑。

点击查看代码
#include<bits/stdc++.h>
using namespace std;

#define int long long
const int N=2010;
int n,k;
int s[N][N],g[N][N];
int up[N][N];
int sta[N],tp;
int l[N],r[N];
int ax,ay,bx,by;
int get(int a,int b,int c,int d)
{
	return s[c][d]+s[a-1][b-1]-s[a-1][d]-s[c][b-1];
}
signed main()
{
//	freopen("matrix.in","r",stdin);
//	freopen("matrix.out","w",stdout);
	scanf("%lld%lld",&k,&n);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			scanf("%lld",&g[i][j]);
			if(g[i][j]>=k&&g[i][j]<=2*k)
			{
				printf("%lld %lld %lld %lld",j,i,j,i);
				exit(0);
			}
			s[i][j]=s[i][j-1]+g[i][j];
		}
		
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			s[i][j]=s[i-1][j]+s[i][j];
			if(s[i][j]>=k&&s[i][j]<=2*k)
			{
				printf("1 1 %lld %lld",j,i);
				exit(0);
			}
		}
	}
	int mx=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(g[i][j]<k)
			{
				up[i][j]=up[i-1][j]+1;
			}
		}
		sta[tp=1]=0;
		up[i][0]=-1;
		for(int j=1;j<=n;j++)
		{
			while(tp&&up[i][sta[tp]]>=up[i][j]) tp--;
			l[j]=sta[tp]+1;
			sta[++tp]=j;
		}
		sta[tp=1]=n+1;
		up[i][n+1]=-1;
		for(int j=n;j>=1;j--)
		{
			while(tp&&up[i][sta[tp]]>=up[i][j]) tp--;
			r[j]=sta[tp]-1;
			sta[++tp]=j;
			
			if(up[i][j])
			{
				int now=get(i-up[i][j]+1,l[j],i,r[j]);
				if(now>=k&&now<=2*k)
				{
					printf("%lld %lld %lld %lld",l[j],i-up[i][j]+1,r[j],i);
					exit(0);
				}
				if(now>mx)
				{
					mx=now;
					ax=i-up[i][j]+1;
					ay=l[i];
					bx=i;
					by=r[j];
				}
			}
		}
	}
	if(mx<k) 
	{
		printf("NTE");
		exit(0);
	}
	for(int i=bx;i>=ax;i--)
	{
		int now=get(i,ay,i,by);
		if(now>=k&&now<=2*k)
		{
			printf("%lld %lld %lld %lld",ay,i,by,i);
			exit(0);
		} 
		if(now>2*k)
		{
			mx=now;
			for(int j=by;j>=ay;j--)
			{
				mx-=g[i][j];
				if(mx>=k&&mx<=k*2)
				{
					printf("%lld %lld %lld %lld",ay,i,j-1,i);
					exit(0);
				}
			}
		}
		else
		{
			mx-=now;
			if(mx>=k&&mx<=2*k)
			{
				printf("%lld %lld %lld %lld",ay,ax,by,i-1);
				exit(0);
			}
		}
	}
}

T3

区间修改和查询很容易的想到了线段树,但赛时没打出来。
先来看下欧拉函数的定义:

那注意一下300这个数字,1到300之间有62个质数,刚好在long long范围内,我们可以考虑用状态压缩来维护这个有关质数的问题,同时我们把欧拉函数分成两部分分开来处理,先预处理出来这62个质数的(p-1)/p,那我们线段树就只需要维护区间每个数的质数情况和乘积。

点击查看代码
#include<bits/stdc++.h>
using namespace std;

#define int long long 
const int mod=1e9+7;
const int N=1e6;
int cnt=62,pr[70]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293};
int n,m;
int a[N],inv[N],tp[N];


int qpow(int a,int b)
{
	int ans=1;
	while(b)
	{
		if(b&1)
		{
			ans=ans*a%mod;
		}
		a=a*a%mod;
		b=b>>1;
	}
	return ans;
}
#define lson (rt<<1)
#define rson (rt<<1|1)

struct lmy
{
	int l,r;
	int pd,lz,fc,lf;
	lmy()
	{
		pd=lz=1;
		fc=lf=0; 
	}
}tr[N<<2];

void pushup(int rt)
{
	tr[rt].pd=tr[lson].pd*tr[rson].pd%mod;
	tr[rt].fc=tr[lson].fc|tr[rson].fc;
}
void pushdown(int rt)
{
	tr[lson].pd=tr[lson].pd*qpow(tr[rt].lz,tr[lson].r-tr[lson].l+1)%mod;
	tr[rson].pd=tr[rson].pd*qpow(tr[rt].lz,tr[rson].r-tr[rson].l+1)%mod;
	tr[lson].lz=tr[lson].lz*tr[rt].lz%mod;
	tr[rson].lz=tr[rson].lz*tr[rt].lz%mod;
	tr[rt].lz=1;
	tr[lson].fc|=tr[rt].lf;
	tr[rson].fc|=tr[rt].lf;
	tr[lson].lf|=tr[rt].lf;
	tr[rson].lf|=tr[rt].lf;
	tr[rt].lf=0;
}
void build(int rt,int l,int r)
{
	tr[rt].l=l;
	tr[rt].r=r;
	if(l==r)
	{
		tr[rt].pd=a[l];
		for(int i=0;i<cnt;i++)
		{
			if(a[l]%pr[i]==0) tr[rt].fc|=((1ll)<<i);
		}
		tr[rt].lz=1;
		return ;
	}
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	pushup(rt);
}
void update(int rt,int l,int r,int c,int f)
{
	if(l<=tr[rt].l&&r>=tr[rt].r)
	{
		tr[rt].pd=tr[rt].pd*qpow(c,tr[rt].r-tr[rt].l+1)%mod;
		tr[rt].lz=tr[rt].lz*c%mod;
		tr[rt].fc|=f;
		tr[rt].lf|=f;
		return ;
	}
	pushdown(rt);
	int mid=(tr[rt].l+tr[rt].r)>>1;
	if(l<=mid) update(lson,l,r,c,f);
	if(r>mid) update(rson,l,r,c,f);
	pushup(rt);
}
int query_pd(int rt,int l,int r)
{
	if(l<=tr[rt].l&&tr[rt].r<=r)
	{
		return tr[rt].pd;
	}
	int ans=1;
	pushdown(rt);
	int mid=(tr[rt].l+tr[rt].r)>>1;
	if(l<=mid) ans=ans*query_pd(lson,l,r)%mod;
	if(r>mid) ans=ans*query_pd(rson,l,r)%mod;
	return ans;
}
int query_fc(int rt,int l,int r)
{
	if(l<=tr[rt].l&&tr[rt].r<=r)
	{
		return tr[rt].fc;
	}
	int ans=0;
	pushdown(rt);
	int mid=(tr[rt].l+tr[rt].r)>>1;
	if(l<=mid) ans|=query_fc(lson,l,r);
	if(r>mid) ans|=query_fc(rson,l,r);
	return ans;
}
void init()
{
	for(int i=2;i<=300;i++)
	{
		inv[i]=qpow(i,mod-2);
	}
	for(int i=0;i<=cnt-1;i++)
	{
		tp[i]=inv[pr[i]]*(pr[i]-1)%mod;
	}
} 
signed main()
{
	freopen("array.in","r",stdin);
	freopen("array.out","w",stdout);
	init();
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		char op[20];
		scanf("%s",op);
		int l,r;
		scanf("%lld%lld",&l,&r);
		if(op[0]=='1')
		{
			int z;
			scanf("%lld",&z);
			int f=0;
			for(int j=0;j<cnt;j++)
			{
				if(z%pr[j]==0) f|=((1ll)<<j);
			}
			update(1,l,r,z,f);
		}
		else
		{
			int x=query_pd(1,l,r);
			int y=query_fc(1,l,r);
			int ans=x;
//			cout<<ans<<" ";
			for(int j=0;j<cnt;j++)
			{
				if((y>>j)&1) ans=ans*tp[j]%mod;
			}
			printf("%lld\n",ans);
		}
	}
}
#T4 先鸽着

标签:rt,int,提高,tr,tp,long,ans,CSP,模拟
From: https://www.cnblogs.com/zhengchenxi/p/18299403

相关文章

  • P1065 [NOIP2006 提高组] 作业调度方案
     首先纠正一下题目错误,红色框应当为3-1,蓝色框应当为3-2 简单概括一下上述题意,首先看输入案例和输出案例代表哪些东西:另外注意以下约束条件对同一个工件,每道工序必须在它前面的工序完成后才能开始;同一时刻每一台机器至多只能加工一个工件。在保证约束条件 (1.)(2.)......
  • 信息学奥赛初赛天天练-45-CSP-J2020阅读程序1-字符数组默认值、字符串长度、字符数组
    PDF文档公众号回复关键字:202407122020CSP-J阅读程序11阅读程序(程序输入不超过数组或字符串定义的范围;判断题正确填√,错误填×。除特殊说明外,判断题1.5分,选择题3分,共计40分)01#include<cstdlib>02#include<iostream>03usingnamespacestd;0405ch......
  • CSP提高组模拟1
    我的微軟輸入法莫名其妙變成繁體了,你們有什麽頭緒嗎狀態題目20TimeExceededA最短路25TimeExceededB方格取数0TimeExceededC数组70TimeExceededD树A.最短路我赛时想了想,会不会DIJ不是很对,因为这个题在打的时候觉得,在跑最短路的时候......
  • 2024.7.12 模拟赛
    A容易观察到每个“\(1\)”相当于是独立的,那么其位置越靠后越优,则对于\(i=1\ton-1\),每次都为\(a_i\)选择一个最大的满足\(i+2^t\leqn\)的\(t\)全部进行操作最优。使用__builtin_clz函数做到\(O(n)\),暴力算\(t\)做到\(O(n\logV)\)。B要想求出每个前缀的答案,就......
  • PGSQL快速生成模拟数据
    背景有时候,我们为了测试数据库的性能,通常需要快速构建测试数据,PgSql提供了快速构建数据的工具,方便我们能够快捷的构建模拟数据。生成函数顺序生成生成SQL--生成一批顺序值SELECTidFROMGENERATE_SERIES(1,10)t(id);结果id1234......
  • 利用产品用途功能,提高业务效率与信息安全
    随着企业业务的不断发展和市场环境的日益复杂,进销存软件作为企业管理的重要工具,其产品用途功能的应用前景愈发广阔。以销售员为例,在传统的进销存管理中,销售员往往能够接触到包括售卖成品原料信息在内的所有产品信息。然而,在实际业务场景中,销售员并不需要了解这些原料信息,......
  • 旧衣回收小程序开发,提高回收效率,实现创收
    随着人们生活水平的提高,对穿衣打扮也越来越重视,衣服更换频率逐渐增高,旧衣回收行业因此产生,并随着市场规模的扩大,拥有了完善的回收产业链,旧衣回收行业的发展不仅能够让大众获得新的赚钱方式,也为我国资源回收利用、保护环境做出了贡献。一、旧衣回收小程序特点旧衣回收市场的......
  • 一文解析:如何提高IP纯净度?
    IP的“清白度”,简而言之,是指一个IP地址在网络环境中的清洁与可信度水平。它反映了该IP地址是否涉及非法活动、是否被滥用,以及是否因频繁异常行为而被网络服务提供商、防火墙或安全系统视为可疑。一个高“清白度”的IP地址,如同网络空间中的一位信誉卓越的公民,能够享受更加自由、......
  • HumanoidBench——模拟仿人机器人算法有未来
    概述论文地址:https://arxiv.org/pdf/2403.10506仿人机器人具有类似人类的外形,有望在各种环境和任务中为人类提供支持。然而,昂贵且易碎的硬件是这项研究面临的挑战。因此,本研究开发了使用先进模拟技术的HumanoidBench。该基准利用仿人机器人评估不同算法的性能,其中包括各......
  • 操作系统课程设计-模拟文件管理系统java实现
    模拟文件管理系统学校的期末课程设计,进行一个简单的分享,不足之处请各位大佬指正。一、主要内容综合运用操作系统理论知识和编程知识设计实现一个可视化操作的文件管理模拟系统,该系统包含的基本信息:创建用户、登录用户、创建文件、删除文件、打开文件、显示文件、关闭文......