ICode9

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

Harbour.Space Scholarship Contest 2021-2022 (open for everyone, rated, Div. 1 + Div. 2)

2021-07-25 10:31:14  阅读:194  来源: 互联网

标签:everyone Contest int s2 s1 re code Div void


A
容易发现只有进位的时候会出现这种情况。
所以直接输出\(\frac{n+1}{10}\)即可。
code:

int T,n;
int main(){
	freopen("1.in","r",stdin);
	scanf("%d",&T);while(T--){
		scanf("%d",&n);printf("%d\n",(n+1)/10);[]
	}
}

B
暴力枚举两个端点,然后折回去看能不能成立时间复杂度\(O(n^3)\)
但是其实可以hash做到\(O(n^2)\),大概是因为B题没有加强。
code:

using namespace std;
int n,m,k,T;char s1[N+5],s2[N+5];
I int check(int l,int r){
	re int i;if(r*2-l<m||r-l+1>m) return 0;for(i=l;i<=r;i++) if(s1[i]^s2[i-l+1]) return 0;
	for(i=r-1;i>=r-(m-(r-l+1));i--) if(s1[i]^s2[r-i+r-l+1])return 0;return 1; 
}
I void solve(){
	re int i,j,h;scanf("%s",s1+1);scanf("%s",s2+1);n=strlen(s1+1);m=strlen(s2+1);
	for(i=1;i<=n;i++){
		for(j=i;j<=n;j++)if(check(i,j)){printf("YES\n");return;}
	}printf("NO\n");
}
int main(){
	freopen("1.in","r",stdin);
	re int i;scanf("%d",&T);while(T--)solve();
}

C
直接对每个问号爆搜然后取个min即可。
code:

using namespace std;
int T,fl[N+5],now1,now2,ans,n=10;char s[N+5];
I void calc(){
	re int i;now1=now2=0;for(i=1;i<=n;i++){
		if(i&1)now1+=(s[i]=='1');else now2+=(s[i]=='1');
		if((now1>now2&&(n-i+1)/2<now1-now2)||(now1<now2&&(n-i)/2<now2-now1)) {ans=min(ans,i);return;}
	}
}
I void dfs(int x){
	if(x==n+1) return calc();if(fl[x]) s[x]='0',dfs(x+1),s[x]='1',dfs(x+1);else dfs(x+1);
}
I void solve(){
	re int i;scanf("%s",s+1);for(i=1;i<=n;i++) fl[i]=(s[i]=='?');ans=10;dfs(1);printf("%d\n",ans);
}
int main(){
	freopen("1.in","r",stdin);
	scanf("%d",&T);while(T--) solve();
}

D
对起点是奇数起点还是偶数起点两个都算一下即可。
注意要判是否在终点之后也是偶数,我就FST在这里。
code:

int T,n,m,r,las,flag;char s1[N+5],s2[N+5];
I void solve(){
	re int i;scanf("%s%s",s1+1,s2+1);n=strlen(s1+1);m=strlen(s2+1);r=1;las=0;flag=0;
	for(i=1;i<=m;i++){
		while(r<=n&&(s1[r]^s2[i]||((r-las)%2==0))) r++;
		if(r==n+1)break;las=r;r+=(i!=m);
	}flag|=(r!=n+1&&(n-r+1)&1);
	r=las=1;for(i=1;i<=m;i++){
		while(r<=n&&(s1[r]^s2[i]||((r-las)%2==0))) r++;
		if(r==n+1)break;las=r;r+=(i!=m);
	}flag|=(r!=n+1&&(n-r+1)&1);
	puts(flag?"Yes":"No");
}
int main(){
	freopen("1.in","r",stdin);
	scanf("%d",&T);while(T--) solve();
}

E
没看到\(m\leq \frac{n}{3}\)太日了。
可以发现我们最多换\(\frac{2n}{3}\)个位置所以有至少\(\frac{n}{3}\)个位置不动。
然后我们又知道一个点只在一个循环中不动。
所以答案不超过\(3\)
然后暴力数连通块个数即可。
code:

int n,m,T,A[N+5],pl[N+5],F[N+5],cnt,Ans[N+5],fa[N+5],ToT,un,wn;
I int Getfa(int x){return x==fa[x]?x:fa[x]=Getfa(fa[x]);}
I void merge(int x,int y){
	un=Getfa(x);wn=Getfa(y);un^wn&&(fa[un]=wn,ToT--);
}
I void Solve(){
	re int i,j;for(i=0;i<=2*n;i++) F[i]=0;cnt=0;scanf("%d%d",&n,&m);for(i=1;i<=n;i++) scanf("%d",&A[i]),pl[A[i]]=i;
	for(i=1;i<=n;i++) pl[i+n]=pl[i];for(i=1;i<=n*2;i++) i>=pl[i]&&(F[i-pl[i]]++);
	for(i=0;i<n;i++){
		if(F[i]<n-2*m) continue;for(j=1;j<=n;j++) fa[j]=j;ToT=n;for(j=i+1;j<=i+n;j++) merge(j-i,pl[j]);
		n-ToT<=m&&(Ans[++cnt]=(n-i)%n);
	}sort(Ans+1,Ans+cnt+1);printf("%d ",cnt);for(i=1;i<=cnt;i++) printf("%d ",Ans[i]);puts("");
}
int main(){
	freopen("1.in","r",stdin);
	re int i;scanf("%d",&T);while(T--) Solve();
}

F
为什么我的分块和树状数组一样快啊。
首先我们考虑这个式子,其实要求\(G_{i-1}+\sum\limits_{j=1}^{i}{A_i\%A_j}+\sum\limits_{j=1}^{i}{A_j\%A_i}\)后面那个实在平凡暴力跳就好了反正调和级数\(O(nlogn)\),我们看前面那个。
拆成\(\sum\limits_{j=1}^{i}{A_i-A_j\times \lfloor \frac{A_i}{A_j}\rfloor}\)
后面那个直接整除分块+树状数组维护即可,时间复杂度\(O(n\sqrt wlog w)\)
然后观察到我们有\(n\)次修改但是有\(n\sqrt w\)次查询,所以按\(\sqrt w\)分块就可以\(O(n\sqrt w)\)了。
但是他们两个跑得一样快……
code:

int n,k,x,y,z,Maxn;ll G[N+5],ToT,A[N+5],F[N+5];
struct Tree{
	ll F[N+5],Q[N+5];
	I void get(int x,int y){re int i;for(i=x;i<x/k*k+k;i++)F[i]+=y;for(i=x/k+1;i<=Maxn/k;i++)Q[i]+=y;}
	I ll find(int x,int y){return (F[y]+Q[y/k])-(F[x-1]+Q[(x-1)/k]);}
}S1,S2; 
I ll calc1(int m){
	re int i,j;ll Ans=0;for(i=1;i<=m;i=j+1)j=m/(m/i),Ans+=1ll*(m/i)*S1.find(i,j);return Ans;
}
I ll calc2(int m){
	re int i,j;ll Ans=0;for(i=0;i<=Maxn;i+=m){
		Ans+=1ll*(i/m)*m*S2.find(i,min(i+m-1,Maxn)); 
	}return Ans;
}
int main(){
	freopen("1.in","r",stdin);freopen("1.out","w",stdout);
	re int i;scanf("%d",&n);k=sqrt(n);for(i=1;i<=n;i++) scanf("%lld",&A[i]),Maxn=max(Maxn,A[i]);
	for(i=1;i<=n;i++){
		G[i]=A[i]*(i-1)+ToT;G[i]-=calc1(A[i])+calc2(A[i]);//printf("%lld %lld\n",calc1(A[i]),calc2(A[i]));
		G[i]+=G[i-1];S1.get(A[i],A[i]);S2.get(A[i],1);ToT+=A[i];printf("%lld ",G[i]);	
	}
}

GHI咕咕咕

标签:everyone,Contest,int,s2,s1,re,code,Div,void
来源: https://www.cnblogs.com/275307894a/p/15057198.html

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

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

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

ICode9版权所有