把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

CF1408F Two Different

题面传送门
一道好题。
首先有一个操作:如果有\(n\)\(a\),\(n\)\(b\),那么可以通过\(n\)次变成\(2n\)\(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]);
}
posted @ 2020-10-07 21:59  275307894a  阅读(34)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end