AFO

ARC103

ARC103E Tr/ee

首先没有叶子显然不科学,\(s_n\)是1也不怎么科学,\(s_i != s_{n-i}\)同样不怎么科学

特判掉上述情况后先把root记为1,链接(root,i+1)如果\(s_i\)就把root改为i+1

理解一下的话就是对于一个这样的结构

如果\(s_i\)就把它做成一颗紫薯

否则一定要去掉这样的结构

就行了


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;

const int M = 1000001;
int n,m,k,a[M],d[M];
char c[M];
int main()
{
	scanf("\n%s",c+1);
	n=strlen(c+1);
	for(int i=1;i<=n;i++) a[i]=c[i]-'0';
	if(!a[1] || a[n]) 
	{
		printf("-1");
		return 0;
	}
	int m=n/2;
	for(int i=1;i<=m;i++) if(a[i]!=a[n-i]) 
	{
		printf("-1");
		return 0;
	}
	k=2;
	printf("1 2\n");
	for(int i=2;i<=m;i++)
	{
		printf("%d %d\n",i+1,k);
		if(a[i]) k=i+1;
	}
	for(int i=m+2;i<=n;i++) printf("%d %d\n",i,k);
}

ARC103F Distance Sums

D值大的一定是叶子。

知道了一个点的子树大小以后就可以找到他的父亲的D(D值不重

然后就可以得到一棵树。但是这棵树并不一定合法比如给每个D都加上一个增量

所以最后再check一下


#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<map>
#define LL long long 
using namespace std;

const int M = 210001;
int n,m,k,a[M],s[M],W,ver[M],nex[M],head[M],cnt;
void add(int x,int y)
{
	ver[++cnt]=y, nex[cnt]=head[x], head[x]=cnt;
	ver[++cnt]=x, nex[cnt]=head[y], head[y]=cnt;
}
map<LL,int> mp;
struct vv
{
	LL x;
	int w;
} t[M];

bool cmp(vv a,vv b){return a.x>b.x;}
bool cmp1(vv a,vv b){return a.w<b.w;}

LL dfs(int x,int fa,int dp)
{
	LL S=s[x];
	for(int i=head[x];i;i=nex[i])
	{
		if(ver[i]==fa) continue;
		S+=dfs(ver[i],x,dp+1);
	}
	return S;
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&t[i].x);
		t[i].w=i; s[i]=1;
		mp[t[i].x]=i;
	}
	sort(t+1,t+1+n,cmp);
	for(int i=1;i<n;i++)
	{
		LL k=t[i].x+(LL)s[t[i].w]-n+s[t[i].w];
		if(k==t[i].x || mp.find(k)==mp.end())
		{
			printf("-1");
			return 0;
		}
		a[t[i].w]=mp[k];
		add(t[i].w,mp[k]);
		s[mp[k]]+=s[t[i].w];
	}
	LL k=dfs(t[n].w,0,0)-n;
	if(dfs(t[n].w,0,0)-n!=t[n].x) 
	{
		printf("-1");
		return 0;
	}
	for(int i=1;i<n;i++) printf("%d %d\n",t[i].w,a[t[i].w]);
}
posted @ 2019-10-09 21:02  ZUTTER☮  阅读(117)  评论(0编辑  收藏  举报