2021.11.15 NOIP模拟

信心赛。除了第四题。

T1

  • 题面
  • 解法
    模拟即可。当时极其懒惰的我用了set,虽然过掉是没有问题,但时间上被手写哈希的xsy大佬吊打……
#include<cstdio>
#include<set>
//#define zczc
using namespace std;
inline void read(int &wh){
	wh=0;int f=1;char w=getchar();
	while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
	while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
	wh*=f;return;
}
inline char get(){
	char w=getchar();
	while(w<'A'||w>'Z')w=getchar();
	return w;
}

struct node{
	int x,y;
};
bool operator <(node s1,node s2){
	return s1.x!=s2.x?s1.x<s2.x:s1.y<s2.y;
}
set<node>a;

signed main(){
	
	#ifdef zczc
	freopen("in.txt","r",stdin);
	#endif
	#ifndef zczc
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
	#endif
	
	int m,x=0,y=0;
	read(m);
	a.insert((node){0,0});
	while(m--){
		switch(get()){
			case 'U':y++;break;
			case 'D':y--;break;
			case 'R':x++;break;
			case 'L':x--;break;
		}
		if(a.count((node){x,y})==0)a.insert((node){x,y});
	}
	printf("%d",a.size());
	
	return 0;
}

T2

  • 题面
  • 解法
    同班的大佬们考完之后纷纷说是找规律,但本蒟蒻硬是没想出来,于是使用了某些奇怪的方法转到线性筛上面了,于是时间再次被吊打。
#include<cstdio>
#include<cstring>
//#define zczc
#define ll long long
using namespace std;
const int N=1000010;
inline void read(int &wh){
	wh=0;int f=1;char w=getchar();
	while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
	while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
	wh*=f;return;
}
inline void check(ll &s1,ll s2){
	if(s1<s2)s1=s2;return;
}
inline ll pow(int wh){
	return (ll)wh*wh*wh;
}

ll f[N],pw[N>>1];
int p[N>>1],cnt;
bool s[N];

signed main(){
	
	#ifdef zczc
	freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	#endif
	#ifndef zczc
	freopen("b.in","r",stdin);
	freopen("b.out","w",stdout);
	#endif
	
	memset(f,-1,sizeof(f));
	f[3]=1;f[4]=2;
	for(int i=2;i<N;i++){
		if(i%3==0)check(f[i],pow(i/3));
		if(i%4==0)check(f[i],pow(i/4)*2);
		if(s[i]==false){
			p[++cnt]=i;
			pw[cnt]=(ll)i*i*i;
		}
		for(int j=1;j<=cnt&&i*p[j]<N;j++){
			check(f[i*p[j]],f[i]*pw[j]);
			s[i*p[j]]=true;
			if(i%p[j]==0)break;
		}
    }
	int m,in;
	read(m);
	while(m--){
		read(in);
		printf("%lld\n",f[in]);
	}
	
	return 0;
}

T3

  • 题面
  • 解法
    枚举每个数作为最小值时的可能的最大的区间长度,更新答案即可。最大的区间长度即是找到某个元素左右第一个比它小的数的位置,用单调栈即可。
#include<cstdio>
#include<stack>
//#define zczc
#define ll long long
using namespace std;
const int N=500010;
inline void read(int &wh){
	wh=0;int f=1;char w=getchar();
	while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
	while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
	wh*=f;return;
}
inline void check(ll &s1,ll s2){
	if(s1<s2)s1=s2;return;
}

int m,a[N],pl[N];
struct node{
	int pl,data;
};
stack<node>st;

signed main(){
	
	#ifdef zczc
	freopen("in.txt","r",stdin);
	#endif
	#ifndef zczc
	freopen("c.in","r",stdin);
	freopen("c.out","w",stdout);
	#endif
	
	read(m);ll ans=0;
	for(int i=1;i<=m;i++)read(a[i]);
	st.push((node){0,-1});
	for(int i=1;i<=m;i++){
		while(st.top().data>=a[i])st.pop();
		pl[i]=st.top().pl;
		st.push((node){i,a[i]});
	}
	while(!st.empty())st.pop();
	st.push((node){m+1,-1});
	for(int i=m;i;i--){
		while(st.top().data>=a[i])st.pop();
		int npl=st.top().pl;
		check(ans,(ll)(npl-pl[i]-1)*a[i]);
		st.push((node){i,a[i]});
	}
	printf("%lld",ans);
	
	return 0;
}

T4

  • 题面
  • 解法
    不说了,咱不会。说是什么LCA的模板题,但咱不会。很好,至少暴搜30分。
posted @ 2021-11-17 14:00  Feyn618  阅读(31)  评论(0编辑  收藏  举报