Codeforces Round #566 Div. 2

  A:n是奇数无解,是偶数为2n/2

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
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;
signed main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	n=read();
	if (n&1) cout<<0;
	else
	{
		ll ans=1;
		for (int i=1;i<=n/2;i++) ans*=2;
		cout<<ans;
	}
	return 0;
	//NOTICE LONG LONG!!!!!
}

  B:随便做。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#define N 510
char getc(){char c=getchar();while (c!='.'&&c!='*') 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,m,a[N][N];
signed main()
{
	n=read(),m=read();
	int qwq=0;
	for (int i=1;i<=n;i++)
		for (int j=1;j<=m;j++)
		{
			char c=getc();
			if (c=='.') a[i][j]=0;
			else a[i][j]=1,qwq++;
		}
	bool flag=0;int cnt=0,tot=0;
	for (int i=2;i<n;i++)
		for (int j=2;j<m;j++)
		if (a[i][j]&&a[i-1][j]&&a[i][j-1]&&a[i+1][j]&&a[i][j+1])
		{
			cnt++;if (cnt>1) {cout<<"NO";return 0;}
			tot++;
			for (int x=i-1;x>=1;x--) if (a[x][j]) tot++;else break;
			for (int x=i+1;x<=n;x++) if (a[x][j]) tot++;else break;
			for (int x=j-1;x>=1;x--) if (a[i][x]) tot++;else break;
			for (int x=j+1;x<=m;x++) if (a[i][x]) tot++;else break;
		}
	if (cnt==0) cout<<"NO";
	else if (tot==qwq) cout<<"YES";
	else cout<<"NO";
	return 0;
	//NOTICE LONG LONG!!!!!
}

  C:码码码。求出每个单词元音个数及最后一个元音。然后看只考虑第二列单词的话最多能配多少对。最后把一些第二列中的单词移到第一列即可。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#define N 100010
char getc(){char c=getchar();while (c!='.'&&c!='*') 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;
struct data
{
	string s;int m,x,y;
	bool operator <(const data&a) const
	{
		return x<a.x||x==a.x&&y<a.y;
	}
}a[N],b[N];
bool flag[N];
string ans[N][2][2];
signed main()
{
	std::ios::sync_with_stdio(false);	
	cin>>n;
	for (int i=1;i<=n;i++) 
	{
		cin>>a[i].s;a[i].m=a[i].s.length();
		for (int j=0;j<a[i].m;j++)
		{
			if (a[i].s[j]=='a') a[i].x++,a[i].y=1;
			if (a[i].s[j]=='e') a[i].x++,a[i].y=2;
			if (a[i].s[j]=='i') a[i].x++,a[i].y=3;
			if (a[i].s[j]=='o') a[i].x++,a[i].y=4;
			if (a[i].s[j]=='u') a[i].x++,a[i].y=5;
		}
	}
	sort(a+1,a+n+1);
	int s=0;
	for (int i=1;i<=n;i++)
	{
		int t=i;
		while (t<n&&a[i].x==a[t+1].x&&a[i].y==a[t+1].y) t++;
		s+=t-i+1>>1;
		i=t;
	}
	int s2=0;
	for (int i=1;i<=n;i++)
	{
		int t=i;
		while (t<n&&a[i].x==a[t+1].x) t++;
		s2+=t-i+1>>1;
		i=t;
	}
	int m=min(s,s2/2);cout<<m<<endl;int tmp=0;
	for (int i=1;i<n;i++)
	if (!flag[i]&&a[i].x==a[i+1].x&&a[i].y==a[i+1].y)
	{
		flag[i]=flag[i+1]=1,tmp++;
		ans[tmp][0][1]=a[i].s,ans[tmp][1][1]=a[i+1].s;
		if (tmp==m) break;
	}
	int u=0;
	for (int i=1;i<=n;i++) if (!flag[i]) b[++u]=a[i];
	int x=1;
	for (int i=1;i<=m;i++)
	{
		while (b[x].x!=b[x+1].x) x++;
		ans[i][0][0]=b[x].s,ans[i][1][0]=b[x+1].s;
		x+=2;
		cout<<ans[i][0][0]<<' '<<ans[i][0][1]<<endl;
		cout<<ans[i][1][0]<<' '<<ans[i][1][1]<<endl;
	}
	return 0;
	//NOTICE LONG LONG!!!!!
}

  D:有各种麻烦的做法。sol的做法似乎比较清真。找到一条直径。直径的两端点可能恰好有一个可以作为根,先check一下。如果都不行,check一下直径中点(显然这是唯一一个可能成为根的非叶节点)。还是不行的话,注意到如果存在合法的根,其与直径中点之间一定是一条链连接,因为一旦有分叉,之前找到的不可能是直径。称与直径中点之间是一条链连接的点为合法点。如果只有一个合法点,直接check即可,否则如果仍存在合法根,树将形成一根扫把,找的离直径中点最近的合法点check即可。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#define N 100010
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],t,deep[N],degree[N],fa[N],f[N],root;
bool flag[N];
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,int from)
{
	for (int i=p[k];i;i=edge[i].nxt)
	if (edge[i].to!=from)
	{
		deep[edge[i].to]=deep[k]+1;
		fa[edge[i].to]=k;
		dfs(edge[i].to,k);
	}
}
bool work(int k,int from)
{
	if (!f[deep[k]]) f[deep[k]]=degree[k];
	else if (degree[k]!=f[deep[k]]) return 0;
	bool flag=1;
	for (int i=p[k];i;i=edge[i].nxt)
	if (edge[i].to!=from) flag&=work(edge[i].to,k);
	return flag;
}
void check(int k){if (k>n) return;memset(f,0,sizeof(f));deep[k]=0;dfs(k,k);if (work(k,k)) {cout<<k;exit(0);}} 
void getnb(int k,int from)
{
	flag[k]=1;
	for (int i=p[k];i;i=edge[i].nxt)
	if (edge[i].to!=from&&degree[edge[i].to]<=2) getnb(edge[i].to,k);
}
signed main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	n=read();if (n==1) {cout<<1;return 0;}
	for (int i=1;i<n;i++)
	{
		int x=read(),y=read();
		addedge(x,y),addedge(y,x);
		degree[x]++,degree[y]++;
	}
	dfs(1,1);
	for (int i=1;i<=n;i++) if (deep[i]>deep[root]) root=i;
	check(root);
	int x=0;
	for (int i=1;i<=n;i++) if (deep[i]>deep[x]) x=i;
	check(x);
	if (deep[root]%2==0)
	{
		check(root);
		for (int _=deep[x]/2;_--;_) x=fa[x];
		check(x);
		getnb(x,x);
		int t=n+1;deep[t]=n;
		for (int i=1;i<=n;i++) if (flag[i]&&i!=x&&deep[i]<deep[t]&&degree[i]==1) t=i;
		check(t);
	}
	cout<<-1;
	return 0;
	//NOTICE LONG LONG!!!!!
}

 

  E:对式子取对数后变为线性递推,矩阵快速幂即可。当然也可以直接递推每个数的贡献。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#define N 100010
#define P 1000000007
#define g 5
#define int long long
char getc(){char c=getchar();while (c!='.'&&c!='*') 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;
}
map<int,int> f;
int ksm(int a,int k) 
{
	int s=1;
	for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;
	return s;
}
int inv(int a){return ksm(a,P-2);}
int BSGS(int a,int b,int p)
{
    int block=sqrt(p),t=1;//cout<<a<<' '<<b<<' '<<p<<endl;
    f.clear();
    for (int i=0;i<block;i++)
    {
        if (f.find(t)==f.end()) f[t]=i;
        if (t==b) return i;
        t=1ll*t*a%p;
    }
    int v=t;
    for (int i=1;i<=(p-1)/block;i++)
    {
        if (f.find(1ll*b*inv(t)%p)!=f.end()) return i*block+f[1ll*b*inv(t)%p];
        t=1ll*t*v%p;
    }
    return -1;
}
ll n,f1,f2,f3,c;
struct matrix
{
	int n,a[5][5];
	matrix operator *(const matrix&b) const
	{
		matrix c;c.n=n;memset(c.a,0,sizeof(c.a));
		for (int i=0;i<n;i++)
			for (int j=0;j<b.n;j++)
				for (int k=0;k<b.n;k++)
				c.a[i][j]=(c.a[i][j]+1ll*a[i][k]*b.a[k][j])%(P-1);
		return c;
	}
}F,a;
signed main()
{
	std::ios::sync_with_stdio(false);
	cin>>n>>f1>>f2>>f3>>c;c=1ll*c*c%P;
	f1=BSGS(g,f1,P);
	f2=BSGS(g,f2,P);
	f3=BSGS(g,f3,P);
	c=BSGS(g,c,P);
	F.n=1;F.a[0][0]=c,F.a[0][1]=c,F.a[0][2]=f1,F.a[0][3]=f2,F.a[0][4]=f3;
	a.n=5;
	a.a[0][0]=1;a.a[0][1]=1;
	a.a[1][1]=1;a.a[1][4]=1;
	a.a[2][4]=1;
	a.a[3][2]=1;a.a[3][4]=1;
	a.a[4][3]=1;a.a[4][4]=1;
	n-=3;for (;n;n>>=1,a=a*a) if (n&1) F=F*a;
	cout<<ksm(g,F.a[0][4]);
	return 0;
	//NOTICE LONG LONG!!!!!
}

  F:没意思不看了。

  小小小小号。result:rank 18 rating +194

 

posted @ 2019-06-16 10:54  Gloid  阅读(...)  评论(...编辑  收藏