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

多校A层冲刺NOIP2024模拟赛06

时间:2024-10-13 09:10:31浏览次数:1  
标签:06 int 多校 mid maxn ans id NOIP2024 op

A. 小 Z 的手套(gloves)

明现的二分,我们先排序,假定 \(a\) 数组个数少,我们就对每一个 \(a_i\) 找一个 \(b_i\) 使其差不超过二分的值,然后

贪心来讲,肯定找相差最大的那组但差不超过二分值的那个数最优,且先找比他小的那组(因为排过序了),然后套个

\(multiset\) 就过了,虽然 \(n{log_n}^2\) 吧

点击查看代码
#include<bits/stdc++.h> 
const int maxn=1e5+10;
using namespace std;
int n,m,a[maxn],b[maxn],ans;
multiset<int>t;
multiset<int>::iterator pos1,pos2;

bool check(int x)
{
	t.clear();
	for(int i=1;i<=m;i++) t.insert(b[i]);
	for(int i=1;i<=n;i++)
	{
		pos1=t.lower_bound(a[i]-x);
//		cout<<a[i]<<" "<<*pos1<<endl;
		if(pos1!=t.end()&&abs(a[i]-*pos1)<=x)
		{
			t.erase(t.find(*pos1));
		}
		else
		{
			pos1=t.upper_bound(x-a[i]);
			if(pos1!=t.end()&&abs(*pos1-a[i])<=x)
			{
				t.erase(t.find(*pos1));
			}
			else return 0;
		}
	}
	return 1;
}

int main()
{
	freopen("gloves.in","r",stdin);
	freopen("gloves.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=m;i++) cin>>b[i];
	sort(a+1,a+1+n),sort(b+1,b+1+m);
	if(n>m)
	{
		for(int i=1;i<=n;i++) swap(a[i],b[i]);
		swap(n,m);
	}
	int l=0,r=1e9;
	while(l<=r)
	{
		int mid=l+r>>1;
		if(check(mid))r=mid-1,ans=mid;
		else l=mid+1;
	}
	cout<<ans;

	return 0;
}
/*

*/

B. 小 Z 的字符串(string)

\(dp\) ,设 \(f_{i,j,k,s}\) 表示前 \(i\) 位,\(j\) 个0,\(k\) 个1,第 \(i\) 位换完后是 \(s\) 的最小代价,因为换两个相同的数是不优的,所以相同的数的

相对位置相同,然后转移就完了

点击查看代码
#include<bits/stdc++.h>
#define pr pair<int,int> 
const int maxn=410;
using namespace std;
int ans,n,cnt[3],f[maxn][maxn>>1][maxn>>1][3],pos[3][maxn];
string s;

int main()
{
	freopen("string.in","r",stdin);
	freopen("string.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>s;n=s.size();s=" "+s;
	for(int i=1;i<=n;i++) pos[s[i]-'0'][++cnt[s[i]-'0']]=i;
	if(cnt[0]>(n+1)/2||cnt[1]>(n+1)/2||cnt[2]>(n+1)/2)
	{
		cout<<-1;
		return 0;
	}
	memset(f,0x7f,sizeof f);
	f[0][0][0][0]=f[0][0][0][1]=f[0][0][0][2]=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<=i&&j<=cnt[0];j++)
		{
			for(int k=0;k+j<=i&&k<=cnt[1];k++)
			{
//				cout<<i<<" "<<j<<" "<<k<<endl;
				int p=i-j-k;
				if(j) f[i][j][k][0]=min(f[i][j][k][0],min(f[i-1][j-1][k][1],f[i-1][j-1][k][2])+abs(i-pos[0][j]));
				if(k) f[i][j][k][1]=min(f[i][j][k][1],min(f[i-1][j][k-1][0],f[i-1][j][k-1][2])+abs(i-pos[1][k]));
				if(p) f[i][j][k][2]=min(f[i][j][k][2],min(f[i-1][j][k][0],f[i-1][j][k][1])+abs(i-pos[2][p]));
			}
		}
	}
	cout<<min(f[n][cnt[0]][cnt[1]][0],min(f[n][cnt[0]][cnt[1]][1],f[n][cnt[0]][cnt[1]][2]))/2;
	
	return 0;
}
/*

*/

C. 一个真实的故事(truth)

发现一个区间只有最左边的 \(1-k\) ,最右边的 \(1-k\) ,区间本身最小的 \(1-k\) 对答案有贡献,用线段数维护最左/右的

\(1-k\) 的位置,合并时把中间 \(2*k\) 个数取出来排序,双指针更新答案

点击查看代码
#include<bits/stdc++.h> 
#define lid id<<1
#define rid id<<1|1
const int maxn=5e4+10;
using namespace std;
int n,k,q,a[maxn];
struct lsx
{
	int l,r,lk[55],rk[55],ans;
}m[maxn<<2];

void up(int id)
{
	for(register int i=1;i<=k;i++)
	{
		m[lid].lk[i]?m[id].lk[i]=m[lid].lk[i]:m[id].lk[i]=m[rid].lk[i];
		m[rid].rk[i]?m[id].rk[i]=m[rid].rk[i]:m[id].rk[i]=m[lid].rk[i];
	}
	pair<int,int> s[110];
	int op=0;
	for(register int i=1;i<=k;i++)
	{
		(m[lid].rk[i]>0)&&(s[++op]={m[lid].rk[i],i},0);	
		(m[rid].rk[i]>0)&&(s[++op]={m[rid].lk[i],i},0);
	}
	sort(s+1,s+1+op);
	int sum=0,cnt[55]={0},l=1,r=1;
	while(l<=op)
	{
		while(r<=op)
		{
			int x=s[r].first,y=s[r].second; 
			if(!cnt[y])sum++;
			cnt[y]++;
			if(sum==k)
			{
				if(!m[id].ans) m[id].ans=s[r].first-s[l].first+1;
				else m[id].ans=min(m[id].ans,s[r].first-s[l].first+1);
				cnt[y]--;
				if(!cnt[y])sum--;
				break;
			}
			r++;
		}
		cnt[s[l].second]--;
		if(!cnt[s[l].second])sum--;
		l++;
	}
	if(m[lid].ans) m[id].ans=min((m[id].ans==0?1000000000:m[id].ans),m[lid].ans);
	if(m[rid].ans) m[id].ans=min((m[id].ans==0?1000000000:m[id].ans),m[rid].ans);
}

inline void build(int id,int l,int r)
{
	m[id].l=l,m[id].r=r;
	if(l==r)
	{
		m[id].lk[a[l]]=m[id].rk[a[l]]=l;
		return; 
	}
	int mid=(l+r)>>1;
	build(lid,l,mid);
	build(rid,mid+1,r);
	up(id);
}

inline void update(int id,int x,int y)
{
	int l=m[id].l,r=m[id].r;m[id].ans=0;
	if(l==r)
	{
		m[id].lk[a[l]]=m[id].rk[a[l]]=0;
		m[id].lk[y]=m[id].rk[y]=l;
		return; 
	}
	int mid=(l+r)>>1;
	x<=mid?update(lid,x,y):update(rid,x,y);
	up(id);
}

int main()
{
	freopen("truth.in","r",stdin);
	freopen("truth.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>k>>q;
	for(register int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	build(1,1,n);
	while(q--)
	{
		int op,x,y;
		cin>>op;
		if(op==1)
		{
			cin>>x>>y;
			update(1,x,y);
			a[x]=y;
		}
		else
		{
			if(!m[1].ans)
			{
				cout<<-1<<'\n';
			}
			else cout<<m[1].ans<<'\n';
		}
	}

	return 0;
}
/*

*/

stars

image

标签:06,int,多校,mid,maxn,ans,id,NOIP2024,op
From: https://www.cnblogs.com/oceansofstars/p/18461883

相关文章

  • [赛记] 多校A层冲刺NOIP2024模拟赛06
    小Z的手套(gloves)100pts最大值最小,考虑二分答案;首先排序,然后每次找出数量较少的那个数组中的每个数$x$在另一个数组中有没有值在范围$[x-mid,x+mid]$的(其中$mid$为二分的答案),其实只需找$x-mid$就行,最后判断一下所有数是否合法即可;因为已经升序排序,所以......
  • 多校A层冲刺NOIP2024模拟赛06
    多校A层冲刺NOIP2024模拟赛06\(T1\)A.小Z的手套(gloves)\(100pts/100pts\)容易发现将选出的左右手套各升序排序后,同一个位置上的两只手套的尺码差距一定在答案的候选集合里,画个数轴分讨一下就证完了。部分分\(20\%\):因为\(n=m\)所以不用管谁选谁不选的问题,故\(......
  • 多校 A 层冲刺 NOIP2024 模拟赛 06
    多校A层冲刺NOIP2024模拟赛06T小Z的手套(gloves)签到题答案显然具有单调性,排序后二分答案即可。T小Z的字符串(string)签到题注意到\(n\)较小,可以使用\(O(n^3)\)的算法,直接上大\(DP\)。设计状态\(f_{i,j,k,0/1/2}\)表示从左往右填到\(i\)位,已经填了\(j\)个\(0......
  • [赛记] 多校A层冲刺NOIP2024模拟赛05
    这场数数好数(number)100pts找三个数的和,而且允许$\Theta(n^2)$,那么我们可以维护出两个数的和,然后每次顺序遍历找这个数减去前面的某个数在任意两个数的和中有没有出现过,这个也是$\Theta(n^2)$的;所以时间复杂度:$\Theta(n^2)$,如果带$\log$会过不去,要用桶维护;点击......
  • 第106天:权限提升-WIN 系统&AD域控&NetLogon&ADCS&PAC&KDC&CVE 漏洞
    知识点1、WIN-域内用户到AD域控-CVE-2014-63242、WIN-域内用户到AD域控-CVE-2020-14723、WIN-域内用户到AD域控-CVE-2021-422874、WIN-域内用户到AD域控-CVE-2022-26923WIN-域控提权-CVE-2014-6324前提条件:1、需要域环境下一台主机普通用户账号密码2、一台主机的管理员权......
  • 多校A层冲刺NOIP2024模拟赛04
    02表示法直接递归即可,稍微写个高精。点击查看代码#include<bits/stdc++.h>usingnamespacestd;//#defineint__int128constintN=1e4;strings;intb[N],c[N],len;inta[N],tot;intread(){ intf=1,s=0;charch=getchar(); while(ch<'0'||ch>'9......
  • 多校A层冲刺NOIP2024模拟赛05
    好数(number没啥好说的直接\(O(n^2)\)枚举即可。点击查看代码#include<bits/stdc++.h>usingnamespacestd;constintN=2e6+107;constintd=2e5;intn,a[N],sum[N];intread(){ intf=1,s=0;charc=getchar(); while(c<'0'||c>'9'){if(c==�......
  • [46] (多校联训) A层冲刺NOIP2024模拟赛06
    HDK在与mt19937_64先生的石头剪刀布比赛中拿下十一连败的好成绩你也来试试吧#include<bits/stdc++.h>usingnamespacestd;#include"include/hdk/rand.h"usingnamespacehdk::Rand;chargetchar_(){charch=getchar();if(ch>='a'andch<='z......
  • 多校A层冲刺NOIP2024模拟赛06
    rank19,T1100pts,T230pts,T345pts,T420ptsT1小Z的手套(gloves)二分答案,贪心匹配\(O(n\logn)\)的check即可。时间复杂度\(O(n\log^2n)\)点此查看代码#include<bits/stdc++.h>#include<bits/extc++.h>//usingnamespace__gnu_pbds;//usingnamespace__gnu_cxx;usi......
  • ABB机器人备件3HAC035065-003
    ABB机器人备件3HAC035065-003是一款重要的伺服电机备件,对于确保ABB机器人的正常运行至关重要。以下是对该备件的详细解析:一、备件信息型号:3HAC035065-003类型:伺服电机备件适用品牌:ABB应用:主要用于ABB机器人的关节驱动,是机器人运动控制的关键部件。二、备件特点与优势高性能......