2024.10.7 模拟赛 多校3

模拟赛

水题场。

T1 colorful

签。

感觉题挺好,正难则反,找出四角都相同的。

在这两排有 6 个四角相同的矩形

对于两排来说,我们只需要记录相同的列的个数,然后能直接算出个数。

发现桶排每次清空复杂度太高,考虑每次只开一排的桶,只会有 \(n\) 个。

code
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 405;
int n,m,tot,c[N][N],cnt[N];
unordered_map<int,int> mp;
LL sum,fac[N];
int main()
{
	freopen("colorful.in","r",stdin);
	freopen("colorful.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) sum+=i*j;
	fac[0]=0; fac[1]=1;
	for(int i=2;i<=m;i++) fac[i]=fac[i-1]+i;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&c[i][j]);
	for(int i=1;i<=n;i++)
	{
		tot=0; mp.clear();
		for(int j=1;j<=m;j++) {if(!mp[c[i][j]]) mp[c[i][j]]=++tot;}
		for(int k=i;k<=n;k++)
		{
			for(int j=1;j<=m;j++)
			{
				if(c[i][j]==c[k][j]) cnt[mp[c[i][j]]]++;
			}
			for(int j=1;j<=tot;j++) sum-=fac[cnt[j]],cnt[j]=0;
		}
	}
	printf("%lld\n",sum);
	return 0;
}

T2 travel

签没签。

区间修改,求和。

赛时糊了一个珂朵莉,但是没有颜色段均摊的珂朵莉是假的!

(想不到差分),区间修改直接想差分,最后遍历一遍统计和就行了。

有一点细节。

点code
#include<bits/stdc++.h> 
using namespace std;
#define LL long long 
#define P pair<int,int>
const int N = 2e6+5,mod = 1e9+7;
int n,m,S,T,tot;
P a[N];
LL ans=1;
inline LL qpow(LL a,int b)
{
	LL res=1;
	while(b)
	{
		if(b&1) res=res*a%mod;
		a=a*a%mod; b>>=1;
	}
	return res;
}
int main()
{
	freopen("travel.in","r",stdin);
	freopen("travel.out","w",stdout);
	scanf("%d%d%d%d",&n,&m,&S,&T);
	for(int i=1;i<=m;i++)
	{
		int c,x,y; scanf("%d%d%d",&c,&x,&y);
		a[++tot]={x,-1}; if(y<T) a[++tot]={y+1,1};
	}
	sort(a+1,a+1+tot); a[0].first=S; a[++tot].first=T+1;
	for(int i=0;i<tot;i++)
	{
		n+=a[i].second;
		if(a[i+1].first>a[i].first)
			ans=(ans*qpow(n,a[i+1].first-a[i].first))%mod;
	}
	printf("%lld\n",ans);
	return 0;
}

T3 线段树

签。

既然断点任选了,那和树也没关系了,就是区间问题,dp。

code
#include<bits/stdc++.h> 
using namespace std;
const int N = 505;
int n,q;
long long s[N][N],f[N][N];

int main()
{
	freopen("segment.in","r",stdin);
	freopen("segment.out","w",stdout);
	scanf("%d%d",&n,&q);
	memset(f,0x3f,sizeof(f));
	for(int i=1;i<=q;i++)
	{
		int x,y; scanf("%d%d",&x,&y);
		s[x][y]++;
	}
	for(int k=1;k<=n;k++)
		for(int i=n;i>=1;i--) s[k][i]+=s[k][i+1];
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++) s[i][k]+=s[i-1][k];
	for(int i=1;i<=n;i++) f[i][i]=s[i][i];
	for(int len=2;len<=n;len++)	
	{
		for(int l=1,r=len+l-1;r<=n;l++,r++)
		{
			for(int k=l;k<r;k++)
			{
				f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]-s[l][r]);
			}
		}
	}
	printf("%lld\n",f[1][n]);
	return 0;
}

T4 薛定谔的猫和巴甫洛夫的狗

巴甫洛夫的狗

trick,统计方案数可以用这种情况出现的概率乘总方案数。

计算概率明显比方案要好求,而且发现是基环树。

找到 \(n\) 所在环编号最小的点作为开始点,然后 dp 向后推是否有猫的概率。

code
#include<bits/stdc++.h>
using namespace std;
const int N = 5e3+5,mod = 1e9+7;
#define LL long long
int T,n;
int fa[N],bl[N],tot,b[N];
char s[N];
inline int find(int x) {return x==fa[x]?(x):(fa[x]=find(fa[x]));}
unordered_map<int,int> mp;
LL inv,p[N],ans;
void init()
{
	mp.clear(); tot=0; ans=0;
	for(int i=1;i<=n;i++) fa[i]=i;
}
inline LL qpow(LL a,int b)
{
	LL res=1;
	while(b)
	{
		if(b&1) res=res*a%mod;
		a=a*a%mod; b>>=1;
	}
	return res;
}
int main()
{
	freopen("experiment.in","r",stdin);
	freopen("experiment.out","w",stdout);
	inv=qpow(2,mod-2);
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%s",&n,s+1); init();
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&b[i]);
			int fx=find(b[i]); fa[find(i)]=fx;
		}
		for(int i=1;i<=n;i++) 
		{
			int fx=find(i); if(!mp[fx]) mp[fx]=++tot;
			bl[i]=mp[fx]; fa[i]=i;
		}
		int fl;
		for(int i=n;i>=1;i--)
		{
			if(bl[i]==bl[n])
			{
				if(find(i)==find(b[i])) fl=i;
				fa[find(i)]=find(b[i]);
			}
		}
		for(int l=0;l<2;l++)
			for(int r=0;r<2;r++)
			{
				for(int i=1;i<=n;i++)
				{
					if(s[i]=='?') p[i]=inv;
					else if(s[i]=='C') p[i]=1;
					else if(s[i]=='.') p[i]=0;
				}
				LL q=0;
				for(int i=1;i<=n;i++)
				{
					if(i==fl)
					{
						q=(l?(p[i]):(mod+1-p[i]))*(r?(p[b[i]]):(mod+1-p[b[i]]))%mod;
						p[i]=l; p[b[i]]=r;
					}
					LL x=p[i],y=p[b[i]];
					p[i]=x*y%mod;
					p[b[i]]=(y+x*(1+mod-y)%mod)%mod;
				}
				ans=(ans+p[n]*q%mod)%mod;	
			}
		int cnt=count(s+1,s+1+n,'?');
		ans=(ans*qpow(2,cnt)%mod);
		printf("%lld\n",ans);
	}
	return 0;
}
posted @ 2024-11-01 16:10  ppllxx_9G  阅读(24)  评论(0编辑  收藏  举报