Codeforces Round #705 (Div. 2)

Contest Link

D - GCD of an Array

给定一个序列,每次将某个位置乘上 \(x\) 并询问当前的 \(\gcd\) ,对 \(1e9+7\) 取模。\(n,q\leq 2e5\) .


明显是拆因子+线段树……但是可以用 unordered_map/cy

//Author: RingweEH
unordered_map<int,map<int,int> >mp,cnt;

void Work( int pos,int x )
{
	for ( int i=2; i<=sqrt(x); i++ )
		while ( x%i==0 )
		{
			mp[pos][i]++; cnt[i][mp[pos][i]]++;
			if ( cnt[i][mp[pos][i]]==n ) ans=ans*i%Mod;
			x/=i;
		}
	if ( x>1 )
	{
		mp[pos][x]++; cnt[x][mp[pos][x]]++;
		if ( cnt[x][mp[pos][x]]==n ) ans=ans*x%Mod;
	}
}

int main()
{
	n=read(); q=read();
	for ( int i=1 ;i<=n; i++ ) a[i]=read(),Work(i,a[i]);
	for ( int pos,x; q; q-- )
		pos=read(),x=read(),Work(pos,x),printf("%lld\n",ans );

	return 0;
}

E - Enormous XOR

定义 \(g(l,r)=x\oplus(x+1)\oplus \cdots\oplus y\)\(f(l,r)=\max\{g(x,y)\},l\leq x\leq y\leq r\) .

给定 \(l,r\) ,求 \(f(l,r)\) .


奇妙结论题。

结论:(默认低位开始 \(0\sim n-1\) 位)

  • 如果 \(l[n-1]\neq r[n-1]\) ,那么答案是 \(11\cdots1\)\(n\) 位)
  • 否则,如果 \(r[0]=1\) ,答案是 \(r\) ;如果 \(r[0]=0\)\(l\leq r-2\) ,答案是 \(r+1\) ;否则,答案是 \(r\) .

Proof

对于第一种情况显然,因为必然包含了一段 \([0111\cdots1,100\cdots0]\) ( 成段的 \(0,1\) 都是 \(n-1\) 个),异或起来就好了。

  • \(r\) 为奇数

考虑归纳证明。\(f(r-1,r)\) 的答案显然是 \(r\) . 现在考虑从 \(f(l,r)\to f(l,r+2)\) .

首先,\(f(r+1,r+2)=r+2\) . 其余段可以分为三种:结尾为 \(r+2,r+1,r\) . 根据归纳假设,第三类的答案是 \(r\) . 第一类的答案由一段 \([l,r]\) 中的段和一段 \([r+1,r+2]\) 组成,后者的异或是 \(1\) ,所以这一类的答案不会超过 \(r+1\) .

对于第二类,假设可以找到大于 \(r+2\) 的答案。那么一定存在一个 \(r+2\) 中为 \(0\) 的位,在答案中为 \(1\) ,由于 \(r+2\) 是奇数,这一位不是第 \(0\) 位。设第一个这一位为 \(1\) 的数是 \(x\) ,显然 \(x\) 必然是个奇数(考虑这一位后面的东西全是 \(1\) ,因为 \(x\) 是从大到小第一个出现这一位是 \(1\) 的),那么 \((x,r+2)\) (不包含)的总数是个奇数(后面的位从偶数到 \(0\) )。而为了让这一位异或结果为 \(1\) ,从 \(x\) 往下的段长必然也是奇数(两个 \(1\) 段之间的 \(0\) 段长度是偶数),所以答案区间的长度是偶数,也就是说 \(n-1\) 位异或出来是 \(0\) ,不可能大于 \(r+2\) 。所以答案只能是 \(r+2\) .

归纳可得,这一种情况的答案是 \(r\) .

  • \(r\) 为偶数

\(f(l,r)\leq f(l,r+1)=r+1\) (因为 \(r+1\) 是奇数),又由于 \(g(r-2,r)=r+1\) ,所以 \(f(l,r)=r+1\) .

//Author: RingweEH
int main()
{
	scanf( "%d",&n ); scanf("%s%s",a,b );
	reverse(a,a+n); reverse(b,b+n);
	if ( a[n-1]!=b[n-1] )
	{
		for ( int i=0; i<n; i++ ) printf("1"); return 0;
	}
	if ( b[0]=='1' ) { reverse(b,b+n); puts(b); return 0; }
	for ( int i=0; i<n; i++ ) l[i]=(a[i]=='1'),r[i]=(b[i]=='1');
	l[0]++;
	for ( int i=0; i<n; i++ ) l[i+1]+=l[i]/2,l[i]%=2;
	if ( l[n] ) { reverse(b,b+n); puts(b); return 0; }
	for ( int i=n-1; i>=0; i-- )
		if ( r[i]>l[i] )
		{
			r[0]++;
			for ( int i=0; i<n; i++ ) r[i+1]+=r[i]/2,r[i]%=2;
			for ( int i=(r[n]) ? n : n-1; i>=0; i-- ) printf("%d",r[i] );
			return 0;
		}
	reverse(b,b+n); puts(b);

	return 0;
}

F - Enchanted Matrix

给定 \(n,m\) ,将整个矩阵划分成每个大小为 \(r\times c\)\(r|n,c|m\) )的子矩阵,使得它们成对相等。求 \((r,c)\) 的方案数。

交互题。询问格式为 ? h w i1 j1 i2 j2 ,询问大小为 \(h\times w\) 且不重叠的、左上角分别为 \((i_1,j_1),(i_2,j_2)\) 的子矩阵是否相等。询问次数上限为 \(3\cdot\lfloor\log_2(n+m)\rfloor\) .


大致思路:行列显然可以独立求出来,分开考虑各自能分的最大块数然后计算其约数,相乘即可。

对于求最大块数:先将 \(n\) (或者 \(m\) )分解质因数,然后 \(\text{Check}\) :当前块长为 \(len\) ,能否分成 \(divi\) 个相同的块。如果 \(divi\) 只有 \(2\) ,那么直接一次询问就能解决。否则,设 \(k\)\(len/divi\) 即每个小块的块长,先比较第一个 \(divi/2\) 和第二个 \(divi/2\) ,再比较第一个 \(divi/2\) 和第二个 \(divi/2\) 加上 \(k\) 是否相等。这样做的原理在于,第二次比较的后一个矩形是第一次比较的后一个矩形往后移一个 \(k\) ,不难证明这样可以直接说明全部小块都相同。

//Author: RingweEH
int Query( int len,int p1,int p2 )	//查询整行/整列,另一维长为len,端点p1p2是否相等
{
	if ( !fl ) printf("? %d %d %d %d %d %d\n",len,m,p1,1,p2,1 );
	else printf("? %d %d %d %d %d %d\n",n,len,1,p1,1,p2 );
	fflush(stdout); int x=read(); return x;
}

//块长是len,分成divi个块,是否相等
bool Check( int len,int divi )
{
	if ( divi==2 ) return Query(len/2,1,len/2+1 );
	int x=len/divi*(divi/2);
	return Query(x,1,x+1) && Query(x,1,x+len/divi+1);
}

//对行/列计算能分的最大块数
int Work( int x )
{
	cnt=0; int nw=x;
	for ( int i=2; i<=nw; i++ )
		if ( nw%i==0 )
		{
			a[++cnt]=i,b[cnt]=0;
			while ( nw%i==0 ) b[cnt]++,nw/=i;
		}
	int res=1;
	for ( int i=1; i<=cnt; i++ )
		for ( int j=1; j<=b[i]; j++ )
			if ( Check(x/res,a[i]) ) res*=a[i];
			else break;
	return res;
}

int Count( int x )
{
	int res=0;
	for ( int i=1; i<=x; i++ ) res+=(x%i==0);
	return res;
}

int main()
{
	n=read(); m=read();
	int ans1=Work(n); fl=1;
	int ans2=Work(m);
	printf("! %d\n",Count(ans1)*Count(ans2) );

	return 0;
}
posted @ 2021-03-07 21:17  MontesquieuE  阅读(80)  评论(0编辑  收藏  举报