首页 > 其他分享 >冲刺CSP联训模拟2

冲刺CSP联训模拟2

时间:2024-10-04 15:13:12浏览次数:1  
标签:return int ll pos 冲刺 联训 ans CSP mod

冲刺CSP联训模拟2

\(T1\) P294. 挤压 \(40pts\)

  • 部分分

    • \(20 \%\) :爆搜,时间复杂度为 \(O(2^{n})\) 。
    • 另外 \(20 \%\) :观察到值域较小,将值域计入状态设计,时间复杂度为 \(O(nV)\) 。
    点击查看代码
    const ll mod=1000000007;
    ll a[100010],p[100010],pp[100010],q[100010],f[2][9000010],ans=0;
    ll qpow(ll a,ll b,ll p)
    {
    	ll ans=1;
    	while(b)
    	{
    		if(b&1)
    		{
    			ans=ans*a%p;
    		}
    		b>>=1;
    		a=a*a%p;
    	}
    	return ans;
    }
    void dfs(ll pos,ll n,ll sum,ll mul)
    {
    	if(pos==n+1)
    	{
    		sum%=mod;
    		ans=(ans+(sum*sum%mod)*mul%mod)%mod;
    	}
    	else
    	{
    		dfs(pos+1,n,sum^a[pos],mul*p[pos]%mod);
    		dfs(pos+1,n,sum,mul*pp[pos]%mod);
    	}
    }
    int main()
    {
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    	ll n,m=0,inv=qpow(1000000000,mod-2,mod),i,j;
    	cin>>n;
    	for(i=1;i<=n;i++)
    	{
    		cin>>a[i];
    		m=max(m,a[i]);
    	}
    	for(i=1;i<=n;i++)
    	{
    		cin>>q[i];
    		p[i]=q[i]*inv%mod;
    		pp[i]=(1000000000-q[i])*inv%mod;
    	}
    	if(n<=28)
    	{
    		dfs(1,n,0,1);
    	}
    	else
    	{
    		m*=2;
    		f[0][0]=1;
    		for(i=1;i<=n;i++)
    		{
    			for(j=0;j<=m;j++)
    			{
    				f[i&1][j]=(f[(i-1)&1][j]*pp[i]%mod+f[(i-1)&1][j^a[i]]*p[i]%mod)%mod;
    			}
    		}
    		for(i=0;i<=m;i++)
    		{
    			ans=(ans+((i%mod)*(i%mod)%mod)*f[n&1][i]%mod)%mod;
    		}
    	}
    	cout<<ans<<endl;
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 正解

    • 按位做,考虑拆平方。
    • 设最终的异或和在二进制表示下(空位补零)为 \((s_{32}s_{31} \dots s_{1}s_{0})_{2}\) ,其平方可以表示成 \(\sum\limits_{i=0}^{32}\sum\limits_{j=0}^{32}s_{i}s_{j}2^{i+j}\) 。
    • 观察到每一项仅与两位有关,那么可以将 \(a_{x}\) 的第 \(i,j\) 位拿出来单独计算其期望。
    • 设 \(f_{k,i,j,0/1,0/1}\) 表示处理到第 \(k\) 个数时,第 \(i\) 位 \(=0/1\) 且第 \(j\) 位 \(=0/1\) 的期望,枚举选或不选转移即可。
    • 最终,有 \(\sum\limits_{i=0}^{32}\sum\limits_{j=0}^{32}f_{n,i,j,1,1}2^{i+j}\) 即为所求。
    点击查看代码
    const ll mod=1000000007;
    ll a[100010],p[100010],q[100010],f[2][35][35][2][2];
    ll qpow(ll a,ll b,ll p)
    {
    	ll ans=1;
    	while(b)
    	{
    		if(b&1)
    		{
    			ans=ans*a%p;
    		}
    		b>>=1;
    		a=a*a%p;
    	}
    	return ans;
    }
    int main()
    {
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    	ll n,inv=qpow(1000000000,mod-2,mod),ans=0,i,j,k,h,l;
    	cin>>n;
    	for(i=1;i<=n;i++)
    	{
    		cin>>a[i];
    	}
    	for(i=1;i<=n;i++)
    	{
    		cin>>q[i];
    		p[i]=q[i]*inv%mod;
    	}
    	for(i=0;i<=32;i++)
    	{
    		for(j=0;j<=32;j++)
    		{
    			f[0][i][j][0][0]=1;
    		}
    	}
    	for(k=1;k<=n;k++)
    	{
    		for(i=0;i<=32;i++)
    		{
    			for(j=0;j<=32;j++)
    			{
    				for(h=0;h<=1;h++)
    				{
    					for(l=0;l<=1;l++)
    					{
    						f[k&1][i][j][h][l]=(f[(k-1)&1][i][j][h][l]*(1-p[k]+mod)%mod+f[(k-1)&1][i][j][h^((a[k]>>i)&1)][l^((a[k]>>j)&1)]*p[k]%mod);
    					}
    				}
    			}
    		}
    	}
    	for(i=0;i<=32;i++)
    	{
    		for(j=0;j<=32;j++)
    		{
    			ans=(ans+f[n&1][i][j][1][1]*qpow(2,i+j,mod)%mod)%mod;
    		}
    	}
    	cout<<ans<<endl;
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

\(T2\) P295. 工地难题 \(25pts\)

  • 当 \(n \ne m\) 时,对于 \(k> \frac{m}{2}\) ,答案显然为 \(2\dbinom{n-(k+1)}{m-k}+\dbinom{n-(k+2)}{m-k}A_{n-(k+2)+1}^{1}=2\dbinom{n-k-1}{m-k}+\dbinom{n-k-2}{m-k}(n-k-1)\) 。

  • 部分分

    • \(20 \%\) :爆搜,递归枚举组合,并及时剪枝。
    点击查看代码
    const ll p=1000000007;
    ll inv[200010],jc[200010],jc_inv[200010],f[200010];
    ll qpow(ll a,ll b,ll p)
    {
    	ll ans=1;
    	while(b)
    	{
    		if(b&1)
    		{
    			ans=ans*a%p;
    		}
    		b>>=1;
    		a=a*a%p;
    	}
    	return ans;
    }
    ll C(ll n,ll m,ll p)
    {
    	return (n>=m&&n>=0&&m>=0)?(jc[n]*jc_inv[n-m]%p)*jc_inv[m]%p:0;
    }
    void dfs(ll pos,ll n,ll sum0,ll sum1,ll maxx,ll pre,ll k)
    {
    	maxx=max(maxx,pre);
    	if(maxx<=k)
    	{
    		if(pos==n+1)
    		{
    			f[maxx]=(f[maxx]+1)%p;
    			return;
    		}
    		else
    		{
    			if(sum0>=1)
    			{
    				dfs(pos+1,n,sum0-1,sum1,maxx,0,k);
    			}
    			if(sum1>=1)
    			{
    				dfs(pos+1,n,sum0,sum1-1,maxx,(pre!=0)*pre+1,k);
    			}
    		}
    	}
    }
    int main()
    {
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    	ll n,m,i;
    	cin>>n>>m;
    	jc[0]=jc_inv[0]=1;
    	for(i=1;i<=n;i++)
    	{
    		inv[i]=qpow(i,p-2,p);
    		jc[i]=jc[i-1]*i%p;
    		jc_inv[i]=jc_inv[i-1]*inv[i]%p;
    	}
    	
    	if(n==m)
    	{
    		for(i=1;i<=n-1;i++)
    		{
    			cout<<0<<" ";
    		}
    		cout<<1<<endl;
    	}
    	else
    	{
    		dfs(1,n,n-m,m,0,0,m/2);
    		for(i=1;i<=m/2;i++)
    		{
    			cout<<f[i]<<" ";
    		}
    		for(i=m/2+1;i<=m;i++)
    		{
    			cout<<(2*C(n-i-1,m-i,p)%p+C(n-i-2,m-i,p)*(n-i-1)%p)%p<<" ";
    		}
    	}
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 正解

\(T3\) P296. 星空遗迹 \(20pts\)

  • 弱化版: QOJ 8046. Rock-Paper-Scissors Pyramid

  • 部分分

    • \(20 \%\) :模拟,时间复杂度为 \(O(qn^{2})\) 。
    点击查看代码
    char s[200010],tmp[200010];
    char w(char x,char y)
    {
    	if(x==y){return x;}
    	if(x!='R'&&y!='R'){return 'S';}
    	if(x!='S'&&y!='S'){return 'P';}
    	if(x!='P'&&y!='P'){return 'R';}
    	return 'A';
    }
    void f(char s[],int len)
    {
    	for(int i=1;i<=len-1;i++)
    	{
    		s[i]=w(s[i],s[i+1]);
    	}
    }
    char ask(int l,int r)
    {
    	for(int i=l,j=1;i<=r;i++,j++)
    	{
    		tmp[j]=s[i];
    	}
    	for(int i=l,j=r-l+1;i<=r;i++,j--)
    	{
    		f(tmp,j);
    	}
    	return tmp[1];
    }
    int main()
    {
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    	int n,q,pd,l,r,i;
    	char c;
    	cin>>n>>q>>(s+1);
    	for(i=1;i<=q;i++)
    	{
    		cin>>pd;
    		if(pd==1)
    		{
    			cin>>l>>c;
    			s[l]=c;
    		}
    		else
    		{
    			cin>>l>>r;
    			cout<<ask(l,r)<<endl;
    		}
    	}
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 正解

\(T4\) P297. 纽带 \(10pts\)

  • 部分分

    • \(10 \%\) :模拟。时间复杂度为 \(O(n! \times n^{3})\) 。

      点击查看代码
      const int mod=1000000007;
      int m[50],p[50],cnt[50],f[3000];
      bool cmp(int l,int r)
      {
      	memset(cnt,0,sizeof(cnt));
      	for(int i=l;i<=r;i++)
      	{
      		cnt[p[i]]++;
      	}
      	for(int i=l;i<=r;i++)
      	{
      		if(cnt[i]==0)
      		{
      			return false;
      		}
      	}
      	return true;
      }
      int main()
      {
      	freopen("a.in","r",stdin);
      	freopen("a.out","w",stdout);
      	int n,sum,flag,l,r,i;
      	cin>>n;
      	for(i=1;i<=n;i++)
      	{
      		cin>>m[i];
      		p[i]=i;
      	}
      	do
      	{
      		sum=0;
      		flag=1;
      		for(l=1;l<=n;l++)
      		{
      			for(r=l;r<=m[l];r++)
      			{
      				flag&=(cmp(l,r)==false);
      				if(flag==0)
      				{
      					break;
      				}
      			}
      			if(flag==0)
      			{
      				break;
      			}
      		}
      		if(flag==1)
      		{
      			for(l=1;l<=n;l++)
      			{
      				for(r=max(l,m[l]+1);r<=n;r++)
      				{
      					sum+=(cmp(l,r)==true);
      				}
      			}
      			f[sum]=(f[sum]+1)%mod;
      		}
      	}while(next_permutation(p+1,p+1+n));
      	for(i=1;i<=n*(n+1)/2;i++)
      	{
      		cout<<f[i]<<" ";
      	}
      	fclose(stdin);
      	fclose(stdout);
      	return 0;
      }
      
    • \(20 \%\) :模拟,枚举右端点和判断是否合法可以继承。时间复杂度为 \(O(n! \times n^{2})\) 。

  • 正解

总结

  • \(T2\) 数组开小挂了 \(5pts\) 。
  • \(T4\) 没有意识到自己判断是否是排列和枚举右端点可以继承,所以写的是 \(O(n! \times n^{3})\) ,挂了 \(10pts\) 。

后记

标签:return,int,ll,pos,冲刺,联训,ans,CSP,mod
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18446609

相关文章

  • 10.4 代码源 2024 CSP-S 模拟赛 Day 9
    省流:\(100+0+0+0=100\)简称:唐诗T1先写了个暴力,然后在想怎么优化,然后想了个区间DP但是写的时候又不会了……然后发现如果这一块数的二进制每一位都有一个数的这一位为\(0\)或者都相同,那么这些数合并起来一定最优,然后双指针搞,复杂度\(O(30n)\)。(这么绕口)赛后听别人说有......
  • [DMY]2024 CSP-S 模拟赛 Day 9
    T2调了1h没调出来,丢了一坨没分的shi扔了。我想放一下作为开头:include<bits/stdc++.h>#defineintlonglongusingnamespacestd;inlineintread(){intw=1,s=0;charch=getchar();while(!isdigit(ch)){if(ch'-')w=-1;ch=getchar();}while(isdigit(ch)){s=s10+(ch-......
  • 【训练记录】2024年莆田市高中信息学奥赛国庆集训CSP-S提高组(第四天场外)
    训练情况rk#1\(100+100+100+100=400\)赛后反思因为满分AK了,就不需要反思了A题显然我们想要选的最多,我们优先选\(a_i\)小的,所以我们对\(a_i\)从小到大排序,再求一个前缀和,再使用二分即可#include<bits/stdc++.h>#defineintlonglongusingnamespaces......
  • CSP-J/S2024总结
    CSP-J/S2024游记初赛前记今年最后一年J了...希望圆我个2年都没有实现的J一等梦还有希望S考好点期待1=day-1考完不放假,然后月考,高兴坏了day1没什么好说的,行就行,不行就AFO(假CSP-J本来就打算摆烂,所以不慌因为是最后一个考场,只有26人,赢!嗯?开局放int?完辣!组合题放那......
  • P9752 [CSP-S 2023] 密码锁&&P8814 [CSP-J 2022] 解密
    GutenTag!Schön,dichzusehen!今天也是很懒惰的一天呢!所以今天三合一!题目:[CSP-S2023]密码锁题目描述小Y有一把五个拨圈的密码锁。如图所示,每个拨圈上是从$0$到$9$的数字。每个拨圈都是从$0$到$9$的循环,即$9$拨动一个位置后可以变成$0$或$8$,因为校园里......
  • CSP-J模拟赛一补题报告
    IAKIOI!!!前言考的最好的一回:240pts首先开T1,45min干掉了然后T2,45min挂了然后T3,40min又挂了然后发呆了一会把T4骗分打了,此时已过去一坤时40minT2切了,最后20min打了T3骗分又发呆了一会T1:100ptsT2:100ptsT3:30ptsT4:10pts《正文》01011010101001010010101011010100011......
  • 联训题单
    总览题单进度备注数据结构13/24-数据结构1STEP读假题了,读成下面这样了:给定01序列,每次单点修改,查询最长的字符相同的连续段长度这不是一眼线段树经典板子题,分别维护左右区间信息以及合并处的信息,然后尝试在中间合并来更新答案十五分钟光速打完拉下样例......
  • 多校A层冲刺 NOIP2024 模拟赛 01
    T1构造字符串签到题注意到\(n\)和\(m\)较小,直接扫一遍用并查集维护他所描述的情况,并将不同的位置记录下来,若存在不同的位置属于同一个集合则不可能构成,否则贪心从前往后取mex即可。时间复杂度\(O(nm\alpha(n))\)。T2寻宝签到题首先先用并查集将大联通块缩点,注意到......
  • CSP-S 2024 第八次
    忘记写了,补一下A依次加入每个\(a_i\),拿个大根堆维护当前以\(i\)结尾的和最大子段,和超过\(s\)了就弹堆顶直到和不超过\(s\)。不过好像出现了一些语文事故,先不管了。B倍增预处理出\(f_i\)表示\(i\)上方第一个大于\(a_i\)的点,询问\(u,v,c\)时,先倍增找到\(u\)上......
  • 『模拟赛』多校A层冲刺NOIP2024模拟赛01
    Rank打得还可以总A.构造字符串签,但是挂了40pts。发现判条件只有相等和不相等,于是想到并查集维护连通块,将强制相同的两个位置的连通块合并,强制不同的先记下,最后统一判断。重点在细节处理,合并连通块时要将位置靠后的合并到靠前的上,注意\(LCP(x,y)=z\)在\(x+z,y+z\le......