CF1408F Two Different

Pro:

Sol:
这种构造题没有什么捷径

就是多手玩,多总结

考虑n=2^k的时候

我们可以用一个简单的分治来构造出合法解

可以很容易的得到2^k个相同的数字

可以总结出这样一个性质
\(2^a\)\(x\)\(2^a\)\(y\)可以合并成\(2^{a+1}\)\(xy\)

考虑n=2^k+c的时候怎么做

把c拆解为\(2^a + 2^b + 2^c +....\)

这个时候我们仍按照刚才分治合并的策略来执行

但这个时候我们会发现由于a b c不连续

所以向上合并的时候会缺少元素

怎么办呢?

不如直接从2^k借一些过来!

我们可以事先预处理是的2^k个元素合并为同一个数字

当处理c不够用是直接从2^k借就可以了!

又由于c<2k所以,2k一定是够用的!

用n=13举个例子
13=8+5

5=1+4

预处理为这种形式

a bbbb

向2^k借一个1

aa bbbb

向2^k借一个2

aaaa bbbb

合并

aaaaaaaa

#include<bits/stdc++.h>
#define N 550000
#define eps 1e-7
#define inf 1e9+7
#define db double
#define ll long long
#define ldb long double
#define ull unsigned long long
using namespace std;
inline int read()
{
	char ch=0;
	int x=0,flag=1;
	while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0',ch=getchar();}
	return x*flag;
}
const int mo=998244353;
int tot;
struct node{int x,y;}p[N];
#define mid ((l+r)>>1)
#define lb(x) ((+x)&(-x))
void solve(int l,int r)
{
	if(l==r)return;
	solve(l,mid);
	solve(mid+1,r);
	for(int i=l,j=mid+1;i<=mid&&j<=r;i++,j++)p[++tot]={i,j};
}
int F(int x,int y)
{
	return ((x^y^(x+y))+(x+y)+(x/y)+(y/x))%mo;
}
int a[N],f[N],g[N],nw[N];
int main()
{
	int n=read(),m=n,cnt=0;
	while(m)a[++cnt]=lb(m),m-=lb(m);
	for(int i=1,k=1;i<=cnt;i++)solve(k,k+a[i]-1),k+=a[i];
	if(cnt<=2)
	{
		printf("%d\n",tot);
		for(int i=1;i<=tot;i++)printf("%d %d\n",p[i].x,p[i].y);
		return 0;
	}
	for(int i=1;i<=a[1];i++)nw[i]=i;
	for(int i=1;i<=n-a[1]-a[cnt];i++)f[i]=a[1]+i;
	for(int i=1;i<=a[cnt];i++)g[i]=n-a[cnt]+i;
	
	for(int i=1,t=0,k=0,len=a[1];i<=cnt-2;i++)
	{
		while(len<a[i+1])
		{
			int tmp=len;
			for(int j=1;j<=tmp;j++)p[++tot]={nw[j],g[++t]},nw[++len]=g[t];
		}
		int tmp=len;
		for(int j=1;j<=tmp;j++)p[++tot]={nw[j],f[++k]},nw[++len]=f[k];
	}
	printf("%d\n",tot);
	for(int i=1;i<=tot;i++)printf("%d %d\n",p[i].x,p[i].y);
	/*
	for(int i=1;i<=n;i++)a[i]=i;
	for(int i=1;i<=tot;i++)
	{
		int x=p[i].x,y=p[i].y;
		a[x]=a[y]=F(a[x],a[y]);
	}
	for(int i=1;i<=n;i++)cout<<a[i]<<endl;
	*/
	return 0;
}
posted @ 2020-10-21 17:37  Creed-qwq  阅读(73)  评论(0编辑  收藏  举报