Codeforces Round #475 Div. 1

  B:当n是偶数时无解,因为此时树中有奇数条边,而我们每次都只能删除偶数条。当n是奇数时一定有解,因为此时不可能所有点度数都为奇数,只要找到一个度数为偶数的点,满足将它删掉后,各连通块大小都为奇数就可以了。考虑如何证明这样的点一定存在。钦定一个根后,考虑找到一个度数为偶数的点,满足子树内点度数均为奇数。这样该点的所有儿子的子树都有奇数个点, 因为删掉该点后每个子树内只有一个点度数为偶数。又因为删掉这个点后该树剩下偶数个点和偶数个连通块,所以该点父亲所在连通块也有奇数个点。

  于是只需要先自底向上删掉度数为偶数的点,再将剩余每棵树自顶向下删除即可。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
	int x=0,f=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x*f;
}
int n,p[N],fa[N],degree[N],t,root;
struct data{int to,nxt;
}edge[N<<1];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs(int k)
{
	for (int i=p[k];i;i=edge[i].nxt)
	{
		dfs(edge[i].to);
		degree[k]+=(degree[edge[i].to]%2==0);
	}
	if ((degree[k]&1)==(k!=root)) printf("%d\n",k);
}
void dfs2(int k)
{
	if ((degree[k]&1)!=(k!=root)) printf("%d\n",k);
	for (int i=p[k];i;i=edge[i].nxt) dfs2(edge[i].to);
}
signed main()
{
#ifndef ONLINE_JUDGE
	freopen("b.in","r",stdin);
	freopen("b.out","w",stdout);
#endif
	n=read();
	for (int i=1;i<=n;i++)
	{
		fa[i]=read();
		if (fa[i]) addedge(fa[i],i);
		else root=i;
	}
	if (n%2==0) {cout<<"NO";return 0;}
	cout<<"YES"<<endl;
	dfs(root);
	dfs2(root);
	return 0;
	//NOTICE LONG LONG!!!!!
}

  C:对于每种矩形宽,找出其各种矩形长的出现次数。如果对某两种宽,其矩形长出现次数的比例不同,显然无解。然后对所有出现次数取gcd即可,gcd的因子数即为答案,即考虑每一行各种矩形长究竟出现了多少次。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
ll gcd(ll n,ll m){return m==0?n:gcd(m,n%m);}
ll read()
{
	ll x=0,f=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x*f;
}
int n,tot;
ll ans;
struct data
{
	ll x,y,z;
	bool operator <(const data&a) const
	{
		return x<a.x||x==a.x&&y<a.y;
	}
}a[N];
void error(){cout<<0;exit(0);}
signed main()
{
#ifndef ONLINE_JUDGE
	freopen("c.in","r",stdin);
	freopen("c.out","w",stdout);
#endif
	n=read();
	for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(),a[i].z=read(),ans=gcd(ans,a[i].z);
	sort(a+1,a+n+1);
	int len=0;
	for (int i=1;i<=n;i++) if (a[i].x==a[1].x) len++;else break;
	if (n%len) error();
	for (int i=1;i<=n;i+=len)
	{
		ll x=0;if (a[i].x==a[i-1].x) error();
		for (int j=i;j<i+len;j++)
		{
			x=gcd(x,a[j].z);
			if (i>len&&(a[j].x!=a[i].x||a[j].y!=a[j-len].y)) error();
		}
		for (int j=i;j<i+len;j++)
		{
			a[j].z/=x;
			if (i>len&&a[j].z!=a[j-len].z) error();
		}
	}
	for (ll i=1;i*i<=ans;i++)
	if (ans%i==0)
	{
		tot++;
		if (i*i!=ans) tot++;
	}
	cout<<tot;
	return 0;
	//NOTICE LONG LONG!!!!!
} 

  

猜你喜欢

转载自www.cnblogs.com/Gloid/p/10422996.html