CF1408F Two Different

fxt275307894a發表於2020-10-07

題面傳送門
一道好題。
首先有一個操作:如果有 n n n a a a, n n n b b b,那麼可以通過 n n n次變成 2 n 2n 2n c c c
那麼考慮倍增,每次選取兩塊拿來合併。
然後對於前一部分和後一部分分別倍增就好了。
程式碼實現:

#include<cstdio>
using namespace std;
int n,m,k,z,a[100039],s,head,x[1000039],y[1000039];
int main(){
//	freopen("1.in","r",stdin);
	register int i,j;
	scanf("%d",&n);
	for(i=0;i<=30;i++) if(n<=(1<<i)) {k=i;break;}
	k--;
	for(i=1;i<=k;i++){
		for(j=1;j<=(1<<k);j++) if(!((j-1)&(1<<i-1))) x[++head]=j,y[head]=j+(1<<i-1);
	}
	for(i=1;i<=k;i++){
		for(j=1;j<=(1<<k);j++) if(!((j-1)&(1<<i-1))) x[++head]=n-j+1,y[head]=n-j+1-(1<<i-1);
	}
	printf("%d\n",head);
	for(i=1;i<=head;i++) printf("%d %d\n",x[i],y[i]);
}

相關文章