返回顶部

暑假集训CSP提高模拟9

又是挂分严重的一场

T1大众点评

image

T1交互题,注意边界处理,还有他的\(compare\)函数返回的是\(1,-1\),我以为是\(1,0\),爆零了
还有特判\(N=1\)的情况

点击查看代码
//#include "ramen.h"
//
//void Ramen(int N) {
//  if(Compare(0, 1) == 1) {
//    Answer(1, 0);
//  } else {
//    Answer(0, 1);
//  }
//}
#include <bits/stdc++.h>
#include "ramen.h"

#define pb push_back
using namespace std;
void Ramen(int N) {
	int n=N-1;
	vector <int> los,win;
	bool vis[N+100]={};
	if(n==0)
	{
		Answer(0,0);
		return;
	}
	
	for(int i=0;i<=n;i+=2)
	{
		if(i+1>n)break;
		vis[i]=vis[i+1]=1;
		if(Compare(i,i+1)==1)
		{
			win.pb(i);
			los.pb(i+1);
		}else
		{
			win.pb(i+1);
			los.pb(i);
		}
	}
	if(!vis[n])
	{
		if(Compare(win[0],n)==1)
		{
			los.pb(n);
		}else 
		{
//			auto it=lower_bound(win.begin(),win.end(),win[0]);
//			win.erase(it,it+1);
			win.pb(n);
		}
	}
	
	int mx=win[0],mi=los[0];
	for(int i=1;i<win.size();i++)
	{
		if(Compare(mx,win[i])==1)continue;
		else mx=win[i];
	}
	for(int i=1;i<los.size();i++)
	{
		if(Compare(mi,los[i])==1)mi=los[i];
		else continue;
	}	
	Answer(mi,mx);
//	if(Compare(0, 1) == 1) (x,y)=1 x>y
//	{
//		Answer(1, 0);
//	} else 
//	{
//		Answer(0, 1);
//	}
}
//g++ -O2 -o grader grader.cpp ROM.cpp
//-std=c++14 -O2 -Wall

\(win10\)情况下,如何运行交互程序

T2录取查询

image

线段树,很显然,说一下易错点

  1. 不能在\(pushup\)中判断\(cnt\)数组的合法性,因为左右还可以扩展,如果你当前让\(f\)变为\(0\),则之后都为\(0\),显然不是我们想要的,所以只需用\(f\)判断递增性即可
    2.然后\(query\)函数返回结构体,再判断\(cnt\)数组的合法性
    3.\(query\)传结构体时,注意赋值,如果当前未处理好,会影响到上一层回溯
点击查看代码
#include <bits/stdc++.h>
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define ull unsigned long long
#define lid (rt<<1)
#define rid (rt<<1|1)
//#define endl '\n'
//#define int long long
#define pb push_back
using namespace std;
const int N = 1e5+5;const ull B=233;
int n,q,cnt[27];
string s,t;
struct Tree
{
	int l,r;bool f;
	char ls;char rs;
	int cnt[28];
//	void clear ()
//	{
//		l=-1;r=-1;f=0;
//		ls=0;rs=0;
//		memset(cnt,0,sizeof cnt);
//	}
}st[N<<2];
inline void pushup(int rt)
{
	int be=25,en=0;
	st[rt].f=(st[lid].f&&st[rid].f&&st[lid].rs<=st[rid].ls);
	for(int i=0;i<=25;i++)
	{
		st[rt].cnt[i]=st[lid].cnt[i]+st[rid].cnt[i];
	}
	st[rt].ls=st[lid].ls;st[rt].rs=st[rid].rs;
}
inline void bt(int rt,int l,int r)
{
//	cout<<rt<<" "<<l<<" "<<r<<endl;
	st[rt].l=l;st[rt].r=r;
	if(l==r)
	{
		st[rt].cnt[s[l]-'a']++;
//		st[rt].zt|=(1<<(s[l-1]-'a'));
		st[rt].f=1;
		st[rt].ls=st[rt].rs=s[l];
		return;
	}
	int mid=(l+r)>>1;
	bt(lid,l,mid);bt(rid,mid+1,r);
	pushup(rt);
//	cout<<l<<" "<<r<<" "<<st[rt].f<<endl;
}
void update(int rt,int l,int r,char v,char ls)
{
	if(l<=st[rt].l&&st[rt].r<=r)
	{
//		cout<<l<<" "<<r<<endl;
		st[rt].cnt[ls-'a']--;//!!!
		st[rt].cnt[v-'a']++;
		st[rt].ls=v;st[rt].rs=v;
		st[rt].f=1;
		return;
	}
	int mid=(st[rt].l+st[rt].r)>>1;
	if(l<=mid)update(lid,l,r,v,ls);
	else update(rid,l,r,v,ls);
	pushup(rt);
}
Tree query(int rt,int l,int r)
{
	if(l<=st[rt].l&&st[rt].r<=r)
	{
//		pushup(rt);
		return st[rt];
	}
	int mid=(st[rt].l+st[rt].r)>>1;
	Tree l1,r1,ans;
	bool vl=0,vr=0;
	if(l<=mid)vl=1,l1=query(lid,l,r);
	if(r>mid)vr=1,r1=query(rid,l,r);
	for(int i=0;i<=25;i++)ans.cnt[i]=l1.cnt[i]+r1.cnt[i];
	if(vl&&vr)
	{
		ans.f=(l1.f&&r1.f&&(l1.rs<=r1.ls));
		ans.ls=l1.ls;ans.rs=r1.rs;		
	}
	else if(vl)ans=l1;
	else if(vr)ans=r1;
	return ans;
}
int main()
{
	speed();
	freopen("2.in","r",stdin);
	freopen("B.out","w",stdout);
	cin>>n>>s>>q;
//	s.insert(0,'0');
	s='*'+s;
	for(int i=1;i<=n;i++)cnt[s[i]-'a']++;
	int op,x,l,r;char c;
	bt(1,1,n);
//	cout<<"*****"<<endl;
	while(q--)
	{
		cin>>op;
		if(op==1)
		{
			cin>>x>>c;
			char ls=s[x];
			
			cnt[s[x]-'a']--;
			s[x]=c;
			cnt[s[x]-'a']++;
			update(1,x,x,c,ls);
		}else
		{
			cin>>l>>r;
			Tree ans=query(1,l,r);
//			cout<<ans.f<<endl;
//			cout<<s.substr(l-1,r-l+1)<<endl;
			if(ans.f)
			{
				bool f=1;
//				cout<<ans.ls<<" "<<ans.rs<<endl;
				for(int i=ans.ls+1;i<=ans.rs-1;i++)
				{
					if(cnt[i-'a']!=ans.cnt[i-'a'])
					{
						f=0;
						break;
					}
				}
				if(f)cout<<"Yes"<<endl;
				else cout<<"No"<<endl;
			}
			else cout<<"No"<<endl;
		}
	}
	return 0;
}

T3精准打击

image

这道题,我考场上的思路是贪心的删最大的\(x\)子树,其实就是如此,一个大小为\(x\)的树,不一定是满\(K\)叉树,我们考虑先使一个大于等于\(x\)二二叉树分离,如果深度不为\(1\)则贡献为\(1\),然后再删他内部的部分子树,贪心的从大往小删,但是值得注意的是,第一次删的最大子树大小是不能确定的,所以我们要枚举,最后答案取\(min\)

点击查看代码
#include <bits/stdc++.h>
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define ull unsigned long long
#define lid (rt<<1)
#define rid (rt<<1|1)
//#define endl '\n'
//#define int long long
#define pb push_back
using namespace std;
const int N = 1e5+5;
ll d,x,k;__int128 p[N];
__int128 qpow(__int128 a,__int128 b)
{
	__int128 ans=1;
	while(b)
	{
		if(b&1)ans=a*ans;
		b>>=1;a=a*a;
	}
	return ans;
}
__int128 fen(ll l,ll r,__int128 x)
{
	ll ans=0;
	while(l<=r)
	{
		ll mid=(l+r)>>1ll;
		if(p[mid+1]-1==x)return mid;
		if(p[mid+1]==x&&mid+1<=d)return mid;
		if(p[mid+1]-1<x)
		{
			ans=mid;
			r=mid-1;
		}else l=mid+1;
	}
	return -ans;
}
void pt(__int128 x)
{
	if(!x)return;
	pt(x/10);
	cout<<1ll*((ll)x%10);
}
int main()
{
	speed();
//	freopen("C.in","r",stdin);
//	freopen("Cc.out","w",stdout);
	int T;
	cin>>T;
	while(T--)
	{
		cin>>d>>k>>x;
		bool ct=0;
		p[0]=1;
		for(ll i=1;i<=d;i++)
		{
			p[i]=p[i-1]*k+1;
		}
		ll cnt=0;ll ans=1e18;
		for(int i=0;i<=d;i++)
		{				
			cnt=0;	ll tx=x;
			
			if((p[i])>=x)
			{
				cnt= !(i==d);
				ll tx=(p[i])-x;ll j=i-1;
				while(tx&&~j)
				{
					cnt+=tx/(p[j]);
					tx%=(p[j]);
					j--;
				}
				ans=min(ans,cnt);
			}
			
		}				
//					ll ans=k-x+1;
		cout<<ans<<endl;

	}
	return 0;
}

image

posted @ 2024-07-27 21:37  wlesq  阅读(16)  评论(0编辑  收藏  举报