zoukankan      html  css  js  c++  java
  • Codeforces Round #554 Div. 2

      A:奇偶配对。

    #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,m,a[N],b[N];
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read(),m=read();
    	int x1=0,x2=0,y1=0,y2=0;
    	for (int i=1;i<=n;i++)
    	{
    		a[i]=read();
    		x1+=a[i]&1,x2+=a[i]&1^1;
    	}
    	for (int i=1;i<=m;i++)
    	{
    		b[i]=read();
    		y1+=b[i]&1,y2+=b[i]&1^1;
    	}
    	cout<<min(x1,y2)+min(x2,y1); 
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      B:从高位到低位考虑,每遇到一个0就考虑将其改成1,即如果该位之后全是0就改下一位,否则改这一位。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 1000010
    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,ans[100],t;
    signed main()
    {
    	n=read();
    	for (int i=19;i>=0;i--)
    	if (!(n&(1<<i)))
    	{
    		if (((n>>i)<<i)==n) 
    		{
    			ans[++t]=i;
    			n^=(1<<i)-1;n++;
    		}
    		else
    		{
    			ans[++t]=i+1;
    			n^=(1<<i+1)-1;n++;
    		}
    	}
    	cout<<t*2<<endl;
    	for (int i=1;i<=t;i++) cout<<ans[i]<<' ';
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      C:显然无论如何变化两者gcd一定是a-b的因子。确定gcd(是某数倍数)的情况下很容易求出最小k。枚举每个因子取最优解即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 1000010
    #define pii pair<ll,int>
    #define mp(x,y) make_pair((x),(y))
    int a,b;
    pii ans;
    pii calc(int x)
    {
    	int t=(x-a%x)%x;
    	return mp(1ll*(a+t)*(b+t)/x,t);
    }
    signed main()
    {
    	cin>>a>>b;
    	if (a<b) swap(a,b);if (a==b) {cout<<0;return 0;}
    	ans.first=1ll*inf*inf;ans.second=inf;
    	for (int i=1;i*i<=a-b;i++)
    	if ((a-b)%i==0)
    	ans=min(ans,calc(i)),ans=min(ans,calc((a-b)/i));
    	cout<<ans.second;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      D:做法似乎非常多。考虑n++后树形态的变化。可以发现是给当前所有没有左儿子的点添加左儿子,并给该左儿子一直添加右儿子直至所有叶子节点深度相同。任意时刻没有左儿子的点都构成很多条链,上述过程就是这些链所引发的,可以考虑dp出各种长度的链的条数,转移考虑上述过程即可。然后考虑怎么利用这个东西求出答案。这棵树的最大匹配可以自底向上贪心求得。画画图观察一下,容易发现最大匹配中各层间是无关的,即上述过程的第一步所添加的边选进最大匹配不会更优。那么一条链对最大匹配的贡献就是链上点的个数/2了。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 1010
    #define P 1000000007
    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,f[N][N],g[N][N],ans;
    signed main()
    {
    	n=read();
    	f[0][1]=1;for (int j=0;j<=n+1;j++) g[0][j]=1;
    	for (int i=1;i<=n;i++)
    	{
    		for (int j=2;j<=i+1;j++)
    		{
    			f[i][j]=g[i-1][j-1];
    			ans=(ans+1ll*f[i][j]*(j>>1))%P;
    		}
    		for (int j=n+1;j>=0;j--) g[i][j]=(g[i][j+1]+f[i][j])%P;
    	}
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      E:除开头和结尾位置上的数都会在给出的数组中的相邻位置出现两次,开头和结尾会各出现一次。将每个数看成一个点,给出的每对数看成一条边,就相当于找一条欧拉路。跑出来再判一下是否合法即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #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,a[N],b[N],p[N],u[N<<1],ans[N],tot,degree[N],cnt,t=-1,top;
    bool flag[N];
    map<int,int> f[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)
    {
    	for (int i=p[k];~i;i=edge[i].nxt)
    	if (!flag[i>>1])
    	{
    		flag[i>>1]=1;
    		p[k]=edge[i].nxt;
    		cnt++;
    		dfs(edge[i].to);
    		ans[top--]=edge[i].to;
    		if (cnt==n-1) break;
    	}
    }
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read();memset(p,255,sizeof(p));
    	for (int i=1;i<n;i++) u[++tot]=a[i]=read();
    	for (int i=1;i<n;i++) u[++tot]=b[i]=read();
    	sort(u+1,u+tot+1);
    	tot=unique(u+1,u+tot+1)-u-1;
    	for (int i=1;i<n;i++) a[i]=lower_bound(u+1,u+tot+1,a[i])-u;
    	for (int i=1;i<n;i++) b[i]=lower_bound(u+1,u+tot+1,b[i])-u; 
    	for (int i=1;i<n;i++) addedge(a[i],b[i]),addedge(b[i],a[i]),degree[a[i]]++,degree[b[i]]++,f[a[i]][b[i]]++;
    	int qwq=0;
    	for (int i=1;i<=tot;i++) if (degree[i]&1) qwq++;
    	if (qwq!=2&&qwq!=0) {cout<<-1;return 0;}
    	top=n;for (int i=1;i<=tot;i++) if (qwq==0||(degree[i]&1)) {dfs(i);ans[1]=i;break;}
    	for (int i=1;i<n;i++)
    	if (f[min(ans[i],ans[i+1])][max(ans[i],ans[i+1])]==0) {cout<<-1;return 0;}
    	else f[min(ans[i],ans[i+1])][max(ans[i],ans[i+1])]--;
    	for (int i=1;i<=n;i++) printf("%d ",u[ans[i]]);
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      F:由于要求每个数各不相同,考虑按数的顺序dp。不妨考虑从大到小。则每次向序列中插入一个数时,需要满足其后一个数-m<=该数。于是设f[i][j][k]为插入i后序列中有j个数其中i~i+m-1在序列中的存在性为k。矩阵快速幂优化。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define P 1000000007
    #define N 210
    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,m,k,ans,size[N];
    struct matrix
    {
    	int n,a[N][N];
    	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;
    		return c;
    	}
    }f,a;
    int trans(int x,int y){return (x<<m)+y;}
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read(),k=read(),m=read();
    	f.n=1;f.a[0][0]=1;
    	a.n=k+1<<m;
    	for (int i=1;i<(1<<m);i++) size[i]=size[i^(i&-i)]+1;
    	for (int i=0;i<=k;i++)
    		for (int j=0;j<(1<<m);j++)
    		{
    			a.a[trans(i,j)][trans(i,(j<<1)&(1<<m)-1)]++;
    			if (i<k) a.a[trans(i,j)][trans(i+1,((j<<1)&(1<<m)-1)|1)]+=size[j]+1;
    		}
    	for (;n;n>>=1,a=a*a) if (n&1) f=f*a;
    	for (int j=0;j<(1<<m);j++) ans=(ans+f.a[0][trans(k,j)])%P;
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      小小小号打的。result:rank 248 rating +166 彻底自闭.jpg

  • 相关阅读:
    About_Web
    神奇的 SQL 之性能优化 → 让 SQL 飞起来
    Java实现Kafka生产者和消费者的示例
    Android屏幕绘制一问到底(无代码)
    关于数据库事务和锁的必会知识点,你掌握了多少?
    【Azure Cloud Services】云服务频繁发生服务器崩溃的排查方案
    Choreographer全解析
    气之争,聊聊算法岗位的门户之见!
    资深首席架构师预测:2021年云计算的8个首要趋势
    【并发编程】- 内存模型(针对JSR-133内存模型)篇
  • 原文地址:https://www.cnblogs.com/Gloid/p/10791840.html
Copyright © 2011-2022 走看看