11.05 代码源 2024 NOIP 模拟赛 Day 4

以后都不再省流了……

T1

题面是依托,光说有 \(x\) 没说是模 \(x\) 还是减 \(x\)

然后瞬间会了一个 \(O(n^2)\) 的 DP

然鹅你用记忆化而不用递推可以多拿 \(10\)

正解是数论分块/根号分治

Code
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define fd(i,a,b) for(int i=(a),_i=(b);i<=_i;i=-~i)
#define bd(i,a,b) for(int i=(a);i>=(b);i=~-i)
#define endl '\n'
using namespace std;

#define SIZE (1<<20)
char In[SIZE],Out[SIZE],*p1=In,*p2=In,*p3=Out;
#define getchar() (p1==p2&&(p2=(p1=In)+fread(In,1,SIZE,stdin),p1==p2)?EOF:*p1++)
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9') {x=x*10+(c-48);c=getchar();}
	return x*f;
}

const int N=2e5+1,B=4e2+1,M=N/B+5,mod=998244353;

int inv[N],f[N],g[M][N];
int que[N],mxn,sqr;

inline int qpow(int x,int y)
{
	int re=1;x%=mod;
	while(y)
	{
		if(y&1) (re*=x)%=mod;
		(x*=x)%=mod,y>>=1;
	}
	return re;
}

inline int add(int x,int y)
{
	return (x+y<mod)?x+y:x+y-mod;
}

inline int del(int x,int y)
{
	return (x<y)?x-y+mod:x-y;
}

signed main()
{
//#define FJ
#ifdef FJ
	freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.02/problem_2770/ex_chess3.in","r",stdin);
	freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.02/problem_2770/chess.out","w",stdout);
#endif
//#define io
#ifdef io
	ios::sync_with_stdio(0);
	cin.tie(0);	cout.tie(0);
#endif
	
	int T=read();
	fd(i,1,T) que[i]=read(),mxn=max(que[i],mxn);
	sqr=min(B-1,(int)sqrt(mxn)+1);
	
	fd(i,1,mxn) inv[i]=qpow(i,mod-2);
	
	fd(i,1,mxn)
	{
		if(i<=sqr) fd(j,1,i) f[i]+=f[i%j];
		else
		{
			fd(j,1,sqr) f[i]+=f[i%j];
			int l=sqr+1,r,k;
			while(l<=i)
			{
				k=i/l,r=i/(i/l);
				if(i<k*(r+1)) f[i]+=g[k][i-l*k];
				else f[i]+=del(g[k][l*k],g[k][i-k*(r+1)]);
				l=r+1;
			}
		}
		f[i]=add(f[i]%mod*inv[i]%mod,1);
		fd(j,1,mxn/sqr)
		{
			if(i<j) g[j][i]=f[i];
			else g[j][i]=add(g[j][i-j],f[i]);
		}
	}

	fd(i,1,T) printf("%lld ",f[que[i]]);
	
	return 0;
}

T2

写的暴力和差分约束的性质

然鹅正解就是 BFS

Code
#include<cstdio>
#include<deque>
#include<vector>
#define fd(i,a,b) for(int i=(a);i<=(b);i=-~i)
#define endl '\n'
using namespace std;

const int N=2e5+509,mod=998244353;

template<typename _T,int SIZ,bool OP>
struct node
{
	static const int D=1e5+1;
	_T a[SIZ];
	inline _T&operator[](int i)
		{return OP?a[i+D]:a[i>0?i:-i];}
};

int n,m,val=9e8,cnt;
node<vector<int>,N,1> e;
node<int,N,1> in;
node<int,N,0> ans;

deque<int> q;
inline void ins(int x)
{
	if(x>0) q.push_front(x);
	if(x<0) q.push_back(x);
}

inline void add(int x,int y)
{
	e[x].push_back(y),++in[y];
}

signed main()
{
// #define FJ
#ifdef FJ
	freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.05/problem_2777/ex_const3.in","r",stdin);
	freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.05/problem_2777/const.out","w",stdout);
#endif
// #define io
#ifdef io
	ios::sync_with_stdio(0);
	cin.tie(0);	cout.tie(0);
#endif
	
	scanf("%d%d",&n,&m);
	
	fd(i,1,m)
	{
		int op,x,y;scanf("%d%d%d",&op,&x,&y);
		if(op==1) add(x,-y),add(y,-x);
		if(op==2) add(-x,y),add(-y,x);
		if(op==3) add(x,y),add(-y,-x);
		if(op==4) add(-x,-y),add(y,x);
	}
	
	fd(i,-n,n) if(!in[i]) ins(i);
	
	while(!q.empty())
	{
		int x=q.front();q.pop_front();
		if(!ans[x]) (ans[x]=x>0?val:-val),--val,++cnt;
		for(const int& y:e[x]) if(--in[y]==0) ins(y);
	}
	
	if(cnt!=n) return puts("NO"),0;
	
	puts("YES");
	fd(i,1,n) printf("%d ",ans[i]);
	
	return 0;
}

T3

没咋看

正解是 DP,目前没懂……

T4

码的 \(O(n^2)\) 的暴力

然鹅有人卡常卡过了 \(O(n^2)\) 的点

赛后才发现时限是 \(3s\)……

35pts
#include<iostream>
#include<cstring>
#define fd(i,a,b) for(int i=(a);i<=(b);++i)

const int N=3001;

int n,tp;
char s[N],st[N];

inline void swap(char &x,char &y)
{
	char t=x;x=y,y=t;
}

inline bool check(char x[])
{
	tp=0;
	fd(i,1,n)
	{
		if(x[i]==st[tp]) --tp;
		else st[++tp]=x[i];
	}
	return tp==0;
}

signed main()
{
	scanf("%s",s+1);
	n=strlen(s+1),st[0]='#';
	
	int ans=0;
	fd(i,1,n) fd(j,i+1,n)
		if(s[i]!=s[j])	swap(s[i],s[j]),ans+=((check(s))),swap(s[i],s[j]);
	
	printf("%d",ans);
	
	return 0;
}

总结

  • 多卡常
  • 好像没有什么了……
posted @ 2024-11-05 19:43  whrwlx  阅读(7)  评论(0编辑  收藏  举报