2022.02.12 模拟赛

T3 rollcall

Step 1

这道题需要两个操作:

1.插入一个值;

2.求第k小的值。

很明显的平衡树,为了不用脑子,上来就是一个Treap。

Step 2

最开始想打FHQ Treap,后来一想,怎么存 \(same[x]\) ?于是放弃挣扎,直接来Treap。

代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm> 
#include<cstring>
#include<bits/stdc++.h>
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;

#define R register
const int N=3e4+10;
int n,m,a[N];
struct node{
	int num,id,ans;
}Q[N];
inline int cmp1(node x,node y){
	return x.num<y.num;
}
inline int cmp2(node x,node y){
	return x.id<y.id;
}
//struct FHQTreap{
	int root,cnt,val[N],key[N],son[N][2],sizei[N],same[N],fa[N];
	inline void update(int x){
		sizei[x]=sizei[son[x][0]]+sizei[son[x][1]]+same[x];
	}
	inline void rotate(int &x,int flag){
		int y=son[x][flag^1];
		int change=son[y][flag];
		son[x][flag^1]=change;
		son[y][flag]=x;
		update(x);
		update(y);
		x=y;
	}
	inline void insert(int &x,int vali){
		if(!x){
			x=++cnt;
			sizei[x]=same[x]=1;
			val[x]=vali;
			key[x]=rand();
			return ;
		}
		if(val[x]==vali)return (void)(++same[x],++sizei[x]);
		int flag=vali>val[x];
		insert(son[x][flag],vali);
		if(key[x]<key[son[x][flag]])rotate(x,flag^1);
		update(x);
	}
	inline int rank_score(int x,int k){
		if(!x)return 0;
		if(sizei[son[x][0]]>=k)return rank_score(son[x][0],k);
		else if(sizei[son[x][0]]+same[x]>=k)return val[x];
		else return rank_score(son[x][1],k-sizei[son[x][0]]-same[x]);
	}
//}treap;

inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*w;
}

signed main(){
	freopen("rollcall.in","r",stdin);
	freopen("rollcall.out","w",stdout);
	n=read();m=read();
	for(R int i=1;i<=n;i++)a[i]=read();
	for(R int i=1;i<=m;i++)Q[i].id=i,Q[i].num=read();
	sort(Q+1,Q+m+1,cmp1);
	int now=1;
	for(R int i=1;i<=m;i++){
		for(;now<=Q[i].num;now++)
		insert(root,a[now]);//,cout<<a[now]<<" ";cout<<endl;
		Q[i].ans=rank_score(root,Q[i].id);
		//cout<<Q[i].ans<<endl;
	}
	sort(Q+1,Q+m+1,cmp2);
	for(R int i=1;i<=m;i++)cout<<Q[i].ans<<endl;
	return 0;
}

T2 car

Step 1

要求是个正方形,不用想,枚举对角线上的两个顶点,计算出其他点的位置,为了省事可以直接上map。

如果出现两个点在一个位置上—— map[make_pair(x,y)]=1 啊/斜眼笑

代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm> 
#include<cstring>
#include<bits/stdc++.h>
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;

#define R register
const int N=1010;
int n;
struct node{
	int x,y;
}car[N];
map<pair<int,int>,int>mapi;

inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*w;
}

signed main(){
	freopen("car.in","r",stdin);
	freopen("car.out","w",stdout);
	n=read();
	for(R int i=1;i<=n;i++){
		car[i].x=read();car[i].y=read();
		mapi[make_pair(car[i].x,car[i].y)]=1;
	}
	int ans=0;
	for(R int i=1;i<=n;i++)
	for(R int j=i+1;j<=n;j++){
		int x=car[i].x,y=car[i].y,u=car[j].x,v=car[j].y;
		int xi=abs(x-u),yi=abs(y-v);
		//if(xi==0||yi==0)continue;
		//if(mapi[make_pair(x,v)]==1&&mapi[make_pair(u,y)]==1)++ans,cout<<x<<" "<<y<<" "<<u<<" "<<v<<endl;
		int x1=u-yi,y1=v+xi,x2=x-yi,y2=y+xi;
		if(mapi[make_pair(x1,y1)]&&mapi[make_pair(x2,y2)])++ans;//,cout<<x<<" "<<y<<" "<<u<<" "<<v<<" "<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl;
	}
	ans/=2;
	cout<<ans;
	return 0;
}

T1 disk

Step 1

简而言之就是有个可爱的栈和一个初始数组,可以进行两个操作:

1.把初始数组里的末尾数字扔进栈里;

2.把栈顶的数字弹出来。

每次可以进行一个操作,并且把被弹出来数字的顺序给了出来,问原来是数组里是否存在某些数字比它后面的数字小的情况。

Step 2

思索一下初始数组和出栈数组的关系:

如果初始数组单调递增,依次从尾至头扔入栈中,设第 \(i\) 个数 \(x\) 出栈,则栈内的数均大于 \(x\) ,并且从栈底到栈顶单调递减。

再思索一下栈内元素大小和出栈数组的关系:

如果栈内元素单调递增,那么出栈数组单调递减,设第 \(i\) 个数 \(x\) 出栈,则栈内元素均小于 \(x\) ,并且从栈底到栈顶单调递增。

所以需要判断每个数后面构成的序列是否递减,或者维护一个最大值,只需要判断比最大值小的序列是否递减,当更换最大值的时候序列清空。

代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm> 
#include<cstring>
#include<bits/stdc++.h>
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;

#define R register
const int N=1e5+10;
int n,a[N],b[N],c[N];

inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*w;
}

signed main(){
	freopen("disk.in","r",stdin);
	freopen("disk.out","w",stdout);
	while(~scanf("%d",&n)){
		for(R int i=1;i<=n;i++)c[i]=a[i]=read();
		sort(a+1,a+n+1);
		int top1=1,top2=1,top3=0;
		for(;top1<=n;top1++){
			if(a[top1]==c[top2])++top2;
			else if(a[top1]<c[top2])b[++top3]=top1;
			else if(a[top1]>c[top2]){
				for(;top3>=1;)
				if(b[top3]==c[top2])--top3,++top2;
				else break;
				if(a[top1]!=c[top2])b[++top3]=a[top1];
				else ++top2;
			}
		}
		int ans=0;
		while(top3){
			if(b[top3]!=c[top2]){
				ans=1;break;
			}else --top3;
			++top2;
		}
		if(ans)puts("J");
		else puts("Y");
	}
	return 0;
}
 posted on 2022-02-12 21:35  eleveni  阅读(53)  评论(0)    收藏  举报