ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

模拟37 考试总结

2021-08-14 07:00:34  阅读:175  来源: 互联网

标签:ch int ll 37 mid 枚举 模拟 卡常 考试


状态有所回升???

考试经过

开题,T1似乎是水题,两个枚举配一个二分,半小时过掉大样例提交带走
T2先写了个爆搜,看了看第二个样例给跑了两分钟,愤而投身正解。。。发现值域不是很大,想到枚举之后去重,于是开始乱搞,两个半小时的时候终于搞出来了,看了看复杂度是\(O(nm\sqrt m)\)的,估计过不去最后的点,给卡了卡常,检查了几遍走了
剩10分钟的时候看T3,发现20分冲不上去,直接return 0骗一分等死
结束100+70+1=171,rank6
T1卡常成功了,顺利骗满;T2 果然没过最后两个点,后悔应该测试点分治

T1.a

枚举\(n^2m\),正解双指针,指针弱者无法实现,然而我阴差阳错加的几个剪枝配合卡常最终助我AC,\(979ms\)惊险通过
放上卡过去的代码

#include <bits/stdc++.h>
using namespace std;
#define R register
char a[35][50050];int b[35][50050];int l,r;
signed main()
{
	int n,m;scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%s",a[i]+1);
	for(int i=1;i<=n;i++)
	 for(int j=1;j<=m;j++)
	  b[i][j]=b[i-1][j]+b[i][j-1]-b[i-1][j-1]+a[i][j]-'0';
	scanf("%d%d",&l,&r);
	long long ans=0;
   for(R int i=1;i<=n;i++)
    for(R int j=i;j<=n;j++)
     for(R int k=1;k<=m;k++)
     {
    	  if(b[j][k]-b[j][k-1]-b[i-1][k]+b[i-1][k-1]>r||b[j][m]-b[j][k-1]-b[i-1][m]+b[i-1][k-1]<l){continue;}
    	  int ans1=0,ans2=0;
    	  int ll=k,rr=m;
    	  if(b[j][k]-b[j][k-1]-b[i-1][k]+b[i-1][k-1]>=l)ans1=k;
    	  else
    	  while(ll<=rr)
    	  {
    	  	  int mid=(ll+rr)>>1;
    	  	  if(b[j][mid]-b[j][k-1]-b[i-1][mid]+b[i-1][k-1]>=l)rr=mid-1,ans1=mid;
    	  	  else ll=mid+1;
    	  }
    	  ll=k;rr=m;
    	  if(b[j][m]-b[j][k-1]-b[i-1][m]+b[i-1][k-1]<=r)ans2=m;
    	  else 
    	  while(ll<=rr)
    	  {
    	  	  int mid=(ll+rr)>>1;
    	  	  if(b[j][mid]-b[j][k-1]-b[i-1][mid]+b[i-1][k-1]<=r)ll=mid+1,ans2=mid;
    	  	  else rr=mid-1;
    	  }
    	  ans+=ans2-ans1+1;
	  }
	cout<<ans<<endl;
	return 0;
}

T2.b

正解在于枚举因数做到\(log\),而我强行分解是根号级别,就差这里
先分别算出每个序列每个因子的贡献次数,将20个相乘,然后再做一次去重操作,将每个因数的贡献减去他所有倍数的贡献即可
这个方法应该积累一下,别上来就硬拆

#include <bits/stdc++.h>
using namespace std;
#define R register
const int mod=1e9+7;
const int N=100050;
inline int read()
{
	int x=0;char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return x;
}
int a[22][N];int n,m;
int yz[22][N],sum[N];
int s[22][N];
signed main()
{	
	cin>>n>>m;int ma=0;
	for(int i=1;i<=n;i++)
	 for(int j=1;j<=m;j++)
      a[i][j]=read(),ma=max(ma,a[i][j]);
	for(int i=1;i<=n;i++)
	 for(int j=1;j<=m;j++)
     s[i][a[i][j]]++;
   for(int i=1;i<=n;i++)
    for(int j=1;j<=ma;j++)
     for(int k=j;k<=ma;k+=j)
      yz[i][j]+=s[i][k];
 	for(R int i=1;i<=ma;i++)
 	{
 		long long an=1;
 		for(R int j=1;j<=n;j++)
 	   an=1ll*an*((1ll*yz[j][i]+1)%mod)%mod;
 	   sum[i]=(1ll*an-1+mod)%mod;
 	}
 	for(int i=ma/2+1;i>=1;i--)
 	{
 		if(!sum[i])continue;
 		for(int j=2*i;j<=ma;j+=i)
 		 sum[i]=(1ll*sum[i]+mod-sum[j])%mod;
 	}
	long long ans=0;
	for(int i=1;i<=ma;i++)ans=(ans+1ll*sum[i]*i%mod)%mod;
	cout<<ans<<endl;
 	return 0;
}

T3.c

点分治+dp,根本调不出来,鸽了
知识点全靠现学,根本学不会
所以这是我点分治入门题???
image
希望有空填坑吧

考试总结

1.把握时间,每分每秒都很珍贵,提高一分,干掉千人
2.思维灵活,从数据范围中寻找突破口,及时更换思路

标签:ch,int,ll,37,mid,枚举,模拟,卡常,考试
来源: https://www.cnblogs.com/PMZG/p/15139772.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有