• Codeforces Round #449 Div. 1


      B:注意到nc/2<=m,于是以c/2为界决定数放在左边还是右边,保证序列满足性质的前提下替换掉一个数使得其更靠近边界即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define P 1000000007
    #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,m,c,a[N],head,tail;
    signed main()
    {
    	n=read(),m=read(),c=read();head=1,tail=n;
    	while (head<=tail)
    	{
    		int x=read();
    		if (x<=c/2)
    		{
    			bool flag=0;
    			for (int i=1;i<head;i++) if (a[i]>x) {cout<<i<<endl;a[i]=x;flag=1;break;}
    			if (!flag) cout<<head<<endl,a[head++]=x;
    		}
    		else
    		{
    			bool flag=0;
    			for (int i=n;i>tail;i--) if (a[i]<x) {cout<<i<<endl;a[i]=x;flag=1;break;}
    			if (!flag) cout<<tail<<endl,a[tail--]=x;
    		}
    	}
    	for (int i=1;i<=n;i++) cout<<a[i]<<' ';cout<<endl;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      D:相当于求有多少个-1 0 1构成的序列满足前缀和始终不小于0且总和在[l,r]中。这个前缀和限制非常容易想到卡特兰数,考虑类似的推式子方法,写出dp式子然后造一个网格图,如果没有前缀和限制只要暴力枚举1的个数算一下组合数即可,而所有不满足前缀和限制的方案与从边界走过来的方案一一对应,于是减掉就可以了(具体见NOI2018冒泡排序?)。于是只剩下模数不是质数的问题,对其分解质因数,然后阶乘及其逆元拆成两部分,与模数互质部分直接处理,剩下的记录每个质因子幂次做前缀和即可求组合数。最坑的一点大概是因为模数可达2e9无法避免爆int。为什么这个小水题过的人这么少

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define int long long
    #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,l,r,fac[N],inv[N],sum[N][30],p[30],t;
    void inc(int &x,int y){x+=y;if (x>=P) x-=P;}
    void exgcd(int &x,int &y,int a,int b)
    {
    	if (b==0)
    	{
    		x=1,y=0;
    		return;
    	}
    	exgcd(x,y,b,a%b);
    	int t=x;x=y;y=t-a/b*x;
    }
    int Inv(int a)
    {
    	int x,y;
    	exgcd(x,y,a,P);
    	return (x%P+P)%P;
    }
    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 C(int n,int m)
    {
    	if (m>n) return 0;
    	int ans=1ll*fac[n]*inv[m]%P*inv[n-m]%P;
    	for (int i=1;i<=t;i++) ans=1ll*ans*ksm(p[i],sum[n][i]-sum[m][i]-sum[n-m][i])%P;
    	return ans;
    }
    int calc(int m)
    {
    	int ans=0;
    	for (int i=0;i<=n;i++)
    	inc(ans,1ll*C(n,i)*C(n-i,m+i)%P);
    	return ans;
    }
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("b.in","r",stdin);
    	freopen("b.out","w",stdout);
    #endif
    	n=read(),P=read(),l=read(),r=read();
    	int u=P;
    	for (int i=2;i*i<=u;i++)
    	if (u%i==0) {p[++t]=i;while (u%i==0) u/=i;}
    	if (u>1) p[++t]=u;fac[0]=1;
    	for (int i=1;i<=n;i++)
    	{
    		int x=i;
    		for (int j=1;j<=t;j++)
    		{
    			sum[i][j]=sum[i-1][j];
    			while (x%p[j]==0) x/=p[j],sum[i][j]++;
    		}
    		fac[i]=1ll*fac[i-1]*x%P;
    	}
    	for (int i=0;i<=n;i++) inv[i]=Inv(fac[i]);
    	cout<<((calc(l)+calc(l+1)-calc(r+2)-calc(r+1))%P+P)%P;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      布星lxl题一点都不会。

  • 相关阅读:
    反转链表 --剑指offer
    链表的倒数第K个节点
    打印1到最大的n位数----java实现
    Permutations java实现
    Generate Parentheses java实现
    Binary Tree Level Order Traversal java实现
    hadoop中日志聚集问题
    PIG的配置
    hadoop2.20.0集群安装教程
    Map/Reduce之间的Partitioner接口
  • 原文地址:https://www.cnblogs.com/Gloid/p/10459521.html
Copyright © 2020-2023  润新知