11.08 NOIP2024模拟赛#17 div1
呜呜呜,糖丸了
发现样例给的很足啊,决定用 Lemon,这样的话赛时就可以估分了……
T1
看了大概 \(5min\) 发现不会
然后就迅速码了个暴力
发现 \(A_i=B_i\) 和另一个特殊性质看起来可写
但是决定先写后面的暴力
把 T2 暴力和链写完了回来看
发现那俩性质其实就是排列组合
码了 \(20min\) 但是调了快 \(45min\)()
Lemon 上拿到了 \(45\) 分
两个特殊性质
else if(fl&&n==m)
{
sort(b+1,b+n+1);
ans=1;int sum=0;//用过的数
//想了半天判有无解才发现保证有解()
fd(i,1,n)
{
int npos=2*(n-i),nnum=b[i]-sum-1;//剩的空位 没选的数
(ans*=A(nnum,npos)%mod)%=mod;//nnum 个数里选 npos 个放进去
// cerr<<npos<<' '<<nnum<<' '<<sum<<' '<<ans<<endl;
sum+=npos+1;
}
printf("%lld\n",ans);
}
else
{
// cerr<<"(m!)="<<A(m,m)<<endl;
// cerr<<"(m!)^(n-1)="<<qpow(A(m,m),n-1)<<endl;
printf("%lld\n",qpow(A(m,m),n-1));
//前 n-1 行在 (i-1)*m ~ i*m-1 随便摆,最后一行不能动
//第 i 行方案数为 (m!)
//(m!)^(n-1)
}
赛后 ZJY 达捞给我讲正解,一听就懂了 %%%sto ZJY orz%%%
赛时其实有想过正解,想到了 \(2\) 种情况,正解是 \(4\) 种情况
另外两种可以乘一下就行了,但赛时觉得不是很对,自己把自己 \(ban\) 了
正解
#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)
#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=2009,M=4e6,mod=998244353;
int n,m,a[N],b[N];
int h[M],w[M],H,W;
inline void init()
{
n=read(),m=read();
H=W=0;
fd(i,1,n*m) h[i]=w[i]=0;
fd(i,1,n) a[i]=read(),h[a[i]]=i;
fd(i,1,m) b[i]=read(),w[b[i]]=i;
}
inline void solve()
{
int ans=1;
bd(i,n*m,1)
{
if(h[i]&&w[i]) ++H,++W;
else if(h[i]||w[i])
{
if(h[i]) (ans*=W)%=mod,++H;
if(w[i]) (ans*=H)%=mod,++W;
}
else (ans*=(H*W+i-n*m))%=mod;
}
printf("%lld\n",ans);
}
void Main()
{
init();
solve();
}
signed main()
{
#define FJ
#ifdef FJ
freopen("pagoda.in","r",stdin);
freopen("pagoda.out","w",stdout);
#else
// freopen("pagoda/ex_pagoda4.in","r",stdin);
// freopen("pagoda/pagoda.out","w",stdout);
#endif
// #define io
#ifdef io
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
#endif
int T=read();
while(T--) Main();
return 0;
}
T2
写的暴力和 \(k=1\) 的情况
雪月花大佬看错题但是想到了正解!%%%%%%
\(k=1\) 只需要看是不是链即可
然后正解是注意到 \(k=2\)(因为 \(k=1\) 可以特判掉),然后进行状压记搜
令 \(f[i][j][msk]\) 表示最后选第 \(i\) 个,倒数第二选第 \(j\) 个,选择的状态为 \(msk\)
赛后写起来不难,但是不好想到这个转化
点击查看代码
#include<cstdio>
#include<algorithm>
#include<unordered_map>
#define ll long long
#define fd(i,a,b) for(int i=(a);i<=(b);i=-~i)
#define endl '\n'
//#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=61,M=100;
int n,m,k,mod;
int e[N][N],d[N];
inline void init()
{
n=read(),m=read(),k=read(),mod=read();
fd(i,1,n) d[i]=0;
fd(i,1,n) fd(j,1,n) e[i][j]=0;
fd(i,1,m)
{
int x=read(),y=read();
e[x][y]=e[y][x]=1;
++d[x],++d[y];
}
}
namespace SubII
{
inline void Main()
{
int cnt=0,cnt2=0;
fd(i,1,n) cnt+=(d[i]==1),cnt2+=(d[i]==2);
if(cnt==2&&cnt2==n-2) puts("2");
else puts("0");
}
}
namespace SubI
{
ll ans,Mx;
#define __conut __builtin_popcountll
std::unordered_map<ll,ll> f[N][N];
inline void clear()
{
fd(i,1,n) fd(j,1,n)
f[i][j].clear();
}
inline void add(ll &x,ll y){x=x+y<mod?x+y:x+y-mod;}
ll F(ll msk,int x,int y)
{
if(f[x][y].count(msk)) return f[x][y][msk];
if(__conut(msk)==2) return f[x][y][msk]=1;
int cnt=0;
fd(i,1,n) if(x!=i&&e[i][y]&&(msk>>(i-1)&1)) ++cnt;
fd(i,1,n) if(x!=i&&y!=i&&(msk>>(i-1)&1)&&!(cnt-e[i][y]))
add(f[x][y][msk],F(msk^(1ll<<(y-1)),i,x));
return f[x][y][msk];
}
inline void Main()
{
Mx=1ll<<n,ans=0,clear();
fd(i,1,n) fd(j,1,n)
if(i!=j) add(ans,F(Mx-1,i,j));
printf("%lld\n",ans);
}
}
void Main()
{
init();
if(n==1) puts("1");
else if(k==1) SubII::Main();
else SubI::Main();
}
signed main()
{
#define FJ
#ifdef FJ
freopen("paradise.in","r",stdin);
freopen("paradise.out","w",stdout);
#else
// freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.08/data/paradise/ex_paradise8.in","r",stdin);
// freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.08/data/paradise/paradise.out","w",stdout);
#endif
// #define io
#ifdef io
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
#endif
int T=read(),ID=read();
while(T--) Main();
return 0;
}
T3
写的暴力,赛后发现字符串可能有相同的,然后暴力就挂了……
改改可以拿到十分
(据说是紫题,所以就不给正解了,给个暴力)
点击查看代码
#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)
#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;
}
template<typename _T,int SIZ>
struct BIT
{
_T c[SIZ+2];
inline void add(int x,_T y)
{
for(;x<=SIZ;x+=(x&-x)) c[x]+=y;
}
inline _T ask(int x)
{
_T res=0;
for(;x;x-=(x&-x)) res+=c[x];
return res;
}
};
const int N=5e5+509,M=5e5+509;
int n,m,k;
//BIT<int,26> t[N];
pair<string,int> s[N];
int rnk[N];
signed main()
{
#define FJ
#ifdef FJ
freopen("firmiana.in","r",stdin);
freopen("firmiana.out","w",stdout);
#else
// freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.08/data/paradise/ex_paradise8.in","r",stdin);
// freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.08/data/paradise/paradise.out","w",stdout);
#endif
// #define io
#ifdef io
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
#endif
n=read(),m=read(),k=read();
fd(i,1,n) cin>>s[i].first,s[i].second=i;
sort(s+1,s+n+1);
string S="#";
int pos=0;
fd(i,1,n)
{
if(s[i].first==S) rnk[s[i].second]=pos;
else S=s[i].first,pos=i,rnk[s[i].second]=pos;
}
while(m--)
{
int op=read();
if(op==1)
{
string P;cin>>P;
fd(i,1,n)
{
fd(j,0,s[i].first.size()-1) s[i].first[j]=P[s[i].first[j]-'a'];
}
sort(s+1,s+n+1);
string S="#";
int pos=0;
fd(i,1,n)
{
if(s[i].first==S) rnk[s[i].second]=pos;
else S=s[i].first,pos=i,rnk[s[i].second]=pos;
}
}
else
{
int x=read();
printf("%lld\n",rnk[x]);
}
}
return 0;
}
T4
黑题中的黑题
暴力没码,T4 最高分 \(4\) 分,为 ZJY 达捞所得 %%%
总结
- T1 没写出来很亏
- T2 思维题,需要练练思维了
本文来自博客园,作者:whrwlx,转载请注明原文链接:https://www.cnblogs.com/whrwlx/p/18535755