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;
}
总结
多卡常- 好像没有什么了……
本文来自博客园,作者:whrwlx,转载请注明原文链接:https://www.cnblogs.com/whrwlx/p/18528654