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

      A:签到。没仔细看数据范围,看到一个O(nt)的差点叉上去了。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define N 110
    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 ans=1000000,ansi=0;
    	for (int i=1;i<=n;i++)
    	{
    		a[i]=read(),b[i]=read();
    		if (a[i]<m) a[i]+=b[i]*((m-a[i]-1)/b[i]+1);
    		if (a[i]<ans) ans=a[i],ansi=i;
    	}
    	cout<<ansi;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      B:从大到小考虑每个数,放在所有能放但还没有放的位置上即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define N 110
    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,h,a[N],b[N],c[N][N],d[N][N]; 
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read(),m=read(),h=read();
    	for (int i=1;i<=m;i++) b[i]=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    		c[i][j]=read();
    	for (int i=h;i>=1;i--)
    		for (int x=1;x<=n;x++)
    			for (int y=1;y<=m;y++)
    			if (c[x][y]&&i<=a[x]&&i<=b[y]&&!d[x][y]) d[x][y]=i;
    	for (int i=1;i<=n;i++)
    	{
    		for (int j=1;j<=m;j++)
    		cout<<d[i][j]<<' ';
    		cout<<endl;
    	}
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      C:在右括号够的情况下尽量放左括号。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define N 300010
    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,c[N][2];char s[N];
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read();
    	scanf("%s",s+1);
    	for (int i=n;i>=1;i--)
    	{
    		c[i][0]=c[i+1][0],c[i][1]=c[i+1][1];
    		if (s[i]=='(') c[i][0]++;
    		if (s[i]==')') c[i][1]++;
    	}
    	int cnt=0;
    	for (int i=1;i<=n;i++)
    	{
    		if (s[i]=='(') cnt++;
    		else if (s[i]==')') cnt--;
    		else
    		{
    			if (n-i-c[i][0]<cnt+c[i][0]+1) s[i]=')',cnt--;
    			else s[i]='(',cnt++;
    		}
    		if (cnt<0||cnt==0&&i<n) goto err;
    	}
    	if (cnt>0) goto err;
    	printf("%s",s+1);
    	return 0;
    	err:cout<<":(";
    	//NOTICE LONG LONG!!!!!
    }
    

      D:这种东西容易想到二分答案,转化成01问题后,设f[i]为要让i号点为1其子树内至少有几个叶子为1,转移显然。dp完之后可以发现压根不需要二分答案。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define N 300010
    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],f[N],fa[N],t,leaves;
    struct data{int to,nxt;
    }edge[N];
    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);
    	if (!p[k]) leaves++,f[k]=1;
    	else
    	if (a[k])
    	{
    		f[k]=N;
    		for (int i=p[k];i;i=edge[i].nxt)
    		f[k]=min(f[k],f[edge[i].to]);
    	}
    	else
    	{ 
    		f[k]=0;
    		for (int i=p[k];i;i=edge[i].nxt)
    		f[k]+=f[edge[i].to];
    	}
    }
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=2;i<=n;i++)
    	{
    		fa[i]=read();
    		addedge(fa[i],i);
    	}
    	dfs(1);
    	cout<<leaves-f[1]+1;
    	return 0;
    	err:cout<<":(";
    	//NOTICE LONG LONG!!!!!
    }
    

      E:询问每一行,考虑其答案的奇偶性,若有奇数,一定有两行均为奇数,头和尾就在这两行内;若没有奇数,说明头和尾在同一行,再询问每一列找到在哪两列即可。确定行/列后直接二分即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define N 1010
    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()
    {
    	n=read();
    	int x=0,y=0;
    	for (int i=1;i<=n;i++)
    	{
    		if (x==0&&i==n) break;
    		cout<<'?'<<' '<<i<<' '<<1<<' '<<i<<' '<<n<<endl;
    		int u=read();
    		if (u&1) if (x) y=i;else x=i;
    	}
    	if (!x)
    	{
    		int ansx[3],ansy[3],cnt=0;
    		for (int i=1;i<=n;i++)
    		{
    			cout<<'?'<<' '<<1<<' '<<i<<' '<<n<<' '<<i<<endl;
    			int u=read();
    			if (u&1)
    			{
    				int l=1,r=n;
    				while (l<r)
    				{
    					int mid=l+r>>1;
    					cout<<"?"<<' '<<l<<' '<<i<<' '<<mid<<' '<<i<<endl;
    					int u=read();
    					if (u&1) r=mid;
    					else l=mid+1;
    				}
    				cnt++;ansx[cnt]=l,ansy[cnt]=i;
    			}
    		}
    		cout<<"!"; 
    		for (int i=1;i<=cnt;i++) cout<<' '<<ansx[i]<<' '<<ansy[i];
    	}
    	else
    	{
    		int ansx[3],ansy[3],cnt=0;
    		int i=x;
    		int l=1,r=n;
    		while (l<r)
    		{
    			int mid=l+r>>1;
    			cout<<"?"<<' '<<i<<' '<<l<<' '<<i<<' '<<mid<<endl;
    			int u=read();
    			if (u&1) r=mid;
    			else l=mid+1;
    		}
    		cnt++;ansx[cnt]=i,ansy[cnt]=l;
    		i=y;
    		l=1,r=n;
    		while (l<r)
    		{
    			int mid=l+r>>1;
    			cout<<"?"<<' '<<i<<' '<<l<<' '<<i<<' '<<mid<<endl;
    			int u=read();
    			if (u&1) r=mid;
    			else l=mid+1;
    		}
    		cnt++;ansx[cnt]=i,ansy[cnt]=l;
    		cout<<"!"; 
    		for (int i=1;i<=cnt;i++) cout<<' '<<ansx[i]<<' '<<ansy[i];
    	}
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      F:不妨设总长度为1,最后再乘l即可。考虑坐标为i的点的贡献,其被k条线段覆盖的概率是C(n,k)pn-k(1-p)k,其中p=i2+(1-i)2=2i2-2i+1。对每个k暴力积分即可,直接暴力进行多项式运算。可能略卡常。场上居然以为积分求逆元要带log,自闭了。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define N 2010
    #define P 998244353
    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,k,l,ans,C[N][N],f[N<<1],h[N<<1],Inv[N<<1],g[N];
    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);}
    void inc(int &x,int y){x+=y;if (x>=P) x-=P;}
    void mul(int m,int *f,int *g,int n)
    {
    	memset(h,0,sizeof(h));
    	for (int i=0;i<=m;i++)
    		for (int j=0;j<min(i+1,n);j++)
    		inc(h[i],1ll*f[i-j]*g[j]%P);
    	for (int i=0;i<=m;i++) f[i]=h[i];
    }
    void div(int m,int *f,int *g,int n)
    {
    	h[2]=f[m],h[1]=f[m-1];f[m]=f[m-1]=0;
    	int x=inv(g[2]);
    	for (int i=m-2;i>=0;i--)
    	{
    		h[0]=f[i];
    		f[i]=1ll*h[2]*x%P;
    		h[2]=(h[1]+P-1ll*g[1]*f[i]%P)%P;
    		h[1]=(h[0]+P-1ll*g[0]*f[i]%P)%P;
    	}
    }
    int calc()
    {
    	int s=0;
    	for (int i=1;i<=n*2+1;i++) inc(s,1ll*f[i-1]*Inv[i]%P);
    	return s;
    }
    signed main()
    {
    	n=read(),k=read(),l=read();
    	C[0][0]=1;
    	for (int i=1;i<=n;i++)
    	{
    		C[i][0]=1;
    		for (int j=1;j<=i;j++)
    		C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;
    	}
    	Inv[0]=Inv[1]=1;for (int i=2;i<=n*2+4;i++) Inv[i]=P-1ll*(P/i)*Inv[P%i]%P;
    	f[0]=1;
    	g[0]=0,g[1]=2,g[2]=P-2;
    	for (int i=1;i<=k;i++) mul(i*2,f,g,3);
    	g[0]=1,g[1]=P-2,g[2]=2;
    	for (int i=1;i<=n-k;i++) mul((i+k)*2,f,g,3);
    	inc(ans,1ll*C[n][k]*calc()%P);
    	for (int i=k+1;i<=n;i++)
    	{
    		g[0]=1,g[1]=P-2,g[2]=2;
    		div(n*2,f,g,3);
    		g[0]=0,g[1]=2,g[2]=P-2;
    		mul(n*2,f,g,3);
    		inc(ans,1ll*C[n][i]*calc()%P);
    	}
    	ans=1ll*ans*l%P;
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
     
    

      小小号打的。result:rank 27 rating +222

  • 相关阅读:
    【Centos7】卸载OpenJDK
    linux 网络测试命令 长期更新
    【Centos7】hostnamectl 设置主机名
    【VMware Workstation】虚拟机静态IP NAT连接外部网络(局域网以及广域网)
    【VMware Workstation】虚拟机动态IP NAT连接外部网络(局域网以及广域网)
    【刷题】BZOJ 4698 Sdoi2008 Sandy的卡片
    【刷题】BZOJ 1717 [Usaco2006 Dec]Milk Patterns 产奶的模式
    【刷题】洛谷 P3809 【模板】后缀排序
    【刷题】BZOJ 2038 [2009国家集训队]小Z的袜子(hose)
    【刷题】洛谷 P2709 小B的询问
  • 原文地址:https://www.cnblogs.com/Gloid/p/10704677.html
Copyright © 2011-2022 走看看