zoukankan      html  css  js  c++  java
  • 20170927 随单题

    随:

    50%有一个dp:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    #define MAXN 100005
    #define re register
    ll n,m,p,a[MAXN],num[MAXN],order[MAXN],tot=0,f[2][MAXN],ans=0,den;
    const ll mod=1e9+7;
    inline ll q_pow(re ll a,re ll b,re ll p){
        re ll res=1;
        while(b){
            if(b&1) res=(res*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        return res%p;
    }
    signed main(){
        scanf("%lld%lld%lld",&n,&m,&p);
        if(n==1){
            re ll b;
            scanf("%lld",&b);
            re ll ans=q_pow(b,m,p)%mod;
            printf("%lld
    ",ans);
            return 0;
        }
        if(p==2){
            puts("1");
            return 0;
        }
        for(ll i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            if(num[a[i]]==0) order[++tot]=a[i];
            num[a[i]]++;
        }
        f[0][1]=1;
        for(ll i=1;i<=m;i++){
            for(ll j=1;j<=p;j++)
                f[i&1][j]=0;
            for(ll j=1;j<=tot;j++){
                ll ord=order[j];
                ll q=num[ord];
                for(ll k=1;k<p;k++)
                    f[i&1][ord*k%p]=(f[i&1][ord*k%p]+f[i&1^1][k]*q)%mod;
            }
        }
        den=q_pow(n,mod-2,mod);
        den=q_pow(den,m,mod);
        for(ll i=1;i<p;i++)
            ans=(ans+f[m&1][i]*i)%mod;
        //printf("%lld %lld
    ",ans,den);
        printf("%lld
    ",ans*den%mod);
        return 0;
    }
    

    100%:原根+瞎搞?

    其实不用怎么做(明明是博主不会原根)

    我们倍增优化这个dp,将m二进制拆分

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    #define MAXN 100005
    #define re register
    ll n,m,p,a[MAXN],f[2][1005],ans=0,den,g[2][1005],nowg=1,nowf=1;
    const ll mod=1e9+7;
    inline ll q_pow(re ll a,re ll b,re ll p){
        re ll res=1;
        while(b){
            if(b&1) res=(res*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        return res%p;
    }
    signed main(){
        scanf("%lld%lld%lld",&n,&m,&p);
        if(n==1){
            re ll b;
            scanf("%lld",&b);
            re ll ans=q_pow(b,m,p)%mod;
            printf("%lld
    ",ans);
            return 0;
        }
        if(p==2){
            puts("1");
            return 0;
        }
        for(ll i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            f[0][a[i]]++;
        }
        den=q_pow(n,mod-2,mod);
        den=q_pow(den,m,mod);
        g[0][1]=1;
        while(m){
            if(m&1){
                for(ll i=0;i<=p;i++)
                    g[nowg][i]=0;
                for(ll i=1;i<p;i++){
                    for(ll j=1;j<p;j++)
                        g[nowg][i*j%p]=(g[nowg][i*j%p]+f[nowf^1][i]*g[nowg^1][j])%mod;
                }
                nowg^=1;
            }
            for(ll i=0;i<=p;i++)
                f[nowf][i]=0;
            for(ll i=1;i<p;i++){
                for(ll j=1;j<p;j++)
                    f[nowf][i*j%p]=(f[nowf][i*j%p]+f[nowf^1][i]*f[nowf^1][j])%mod;
            }
            nowf^=1;
            m>>=1;
        }
        for(ll i=1;i<p;i++)
            ans=(ans+g[nowg^1][i]*i)%mod;
        //printf("%lld %lld
    ",ans,den);
        printf("%lld
    ",ans*den%mod);
        return 0;
    }
    

    单:

    40%:n2暴力+n3高斯消元

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define ll long long
    #define MAXN 100005
    #define re register
    #define eps (1e-8)
    using namespace std;
    ll t,n,type,a[MAXN],b[MAXN];
    bool flag=1;
    ll to[MAXN<<1],nxt[MAXN<<1],pre[MAXN],cnt=0;
    inline void add(re ll u,re ll v){
    	cnt++,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt;
    }
    ll f[MAXN][20],deep[MAXN];
    inline void dfs(re ll x){
    	for(re ll i=1;i<=18;i++){
    		if(f[x][i-1])
    		f[x][i]=f[f[x][i-1]][i-1];
    	}
    	for(re ll i=pre[x];i;i=nxt[i]){
    		if(to[i]!=f[x][0]){
    			deep[to[i]]=deep[x]+1;
    			f[to[i]][0]=x;
    			dfs(to[i]);
    		}
    	}
    }
    inline ll LCA(re ll x,re ll y){
    	if(deep[x]<deep[y]) swap(x,y);
    	re ll k=deep[x]-deep[y];
    	for(re ll i=0;i<=18;i++)
    		if((1<<i)&k)
    			x=f[x][i];
    	if(x==y) return x;
    	for(re ll i=18;i>=0;i--)
    		if(f[x][i]!=f[y][i])
    			x=f[x][i],y=f[y][i];
    	return f[x][0];
    }
    double g[10005][10005];
    inline void gs(){
    	for(re ll i=1;i<=n;i++){
            re ll p=i;
            for(re ll j=i+1;j<=n;j++)
    			if(fabs(g[j][i])>fabs(g[p][i]))
    				p=j;
            for(re ll j=1;j<=n+1;j++)
    			swap(g[p][j],g[i][j]);
            if(fabs(g[i][i])<eps) continue;
            double tmp=g[i][i];
            for(re ll j=1;j<=n+1;j++)
    			g[i][j]/=tmp;
            for(re ll j=1;j<=n;j++)
                if(i!=j){
                    double temp=g[j][i];
                    for(re ll k=1;k<=n+1;k++)
    					g[j][k]-=g[i][k]*temp;
                }
        }
    }
    signed main(){
    	scanf("%lld",&t);
    	while(t--){
    		scanf("%lld",&n);
    		for(re ll i=1,u,v;i<n;i++){
    			scanf("%lld%lld",&u,&v);
    			if(v!=u+1) flag=0;
    			add(u,v),add(v,u);
    		}
    		dfs(1);
    		scanf("%lld",&type);
    		if(type==0){
    			for(re ll i=1;i<=n;i++){
    				scanf("%lld",&a[i]);
    			}
    			for(re ll i=1;i<=n;i++){
    				for(re ll j=1;j<=n;j++){
    					if(i==j){
    						continue;
    					}
    					re ll lca,dis;
    					if(flag==1)
    						dis=abs(i-j);
    					else{
    						lca=LCA(i,j);
    						dis=deep[i]+deep[j]-2*deep[lca];
    					}
    					b[i]+=a[j]*dis;
    				}
    				printf("%lld ",b[i]);
    			}
    			puts("");
    		}else{
    			for(re ll i=1;i<=n;i++){
    				scanf("%lld",&b[i]);
    				g[i][n+1]=(double)b[i];
    			}
    			for(re ll i=1;i<=n;i++){
    				for(re ll j=1;j<=n;j++){
    					if(i==j){
    						g[i][j]=0;
    						continue;
    					}
    					re ll lca,dis;
    					if(flag==1)
    						dis=abs(i-j);
    					else{
    						lca=LCA(i,j);
    						dis=deep[i]+deep[j]-2*deep[lca];
    						//printf("%lld %lld
    ",lca,dis);
    					}
    					g[i][j]=(double)dis;
    				}
    			}
    			gs();
    			for(re ll i=1;i<=n;i++){
    				//if(fabs(g[i][n+1])<eps) printf("0 ");
    				//else 
    				printf("%.0lf ",g[i][n+1]);
    			}
    			puts("");
    		}
    		memset(f,0,sizeof(f));
    		memset(pre,0,sizeof(pre));
    		//memset(a,0,sizeof(a));
    		memset(b,0,sizeof(b));
    		cnt=deep[1]=0;
    		flag=1;
    	}
    	return 0;
    }
    
    /*
    7
    1 2
    1 3
    2 4
    2 5
    4 6
    4 7
    
    
    10
    5
    1 2
    1 3
    2 4
    2 5
    0
    6 8 7 1 3
    5
    1 2
    1 3
    2 4
    2 5
    1
    23 24 34 47 43
    5
    1 2
    1 3
    2 4
    2 5
    0
    19 2 1 14 3
    5
    1 2
    1 3
    2 4
    2 5
    1
    37 38 74 49 71
    
    4
    1 2
    2 3
    3 4
    0
    5 7 10 8
    
    
    4
    1 2
    2 3
    3 4
    1
    51 31 25 39
    
    6
    1 2
    1 3
    1 4
    2 5
    2 6
    0
    5 7 9 1 3 2
    
    6
    1 2
    1 3
    1 4
    2 5
    2 6
    1
    27 30 36 52 51 53
    */
    

    100%:我能不能不在这里推式子呀?毕竟把别人提解粘过来不太好

    那我就放个链接把大家骗到小红博客里:

    https://www.cnblogs.com/Rorschach-XR/p/11255318.html

    rp++

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define ll long long
    #define MAXN 100005
    #define re register
    using namespace std;
    ll t,n,type,a[MAXN],b[MAXN];
    ll to[MAXN<<1],nxt[MAXN<<1],pre[MAXN],cnt=0;
    inline void add(re ll u,re ll v){
    	cnt++,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt;
    }
    ll deep[MAXN],sum=0,size[MAXN];//size[i]表示i的子数中a[son]的和
    void dfs_1(re ll x,re ll fa){
    	for(ll i=pre[x];i;i=nxt[i]){
    		ll y=to[i];
    		if(y==fa) continue;
    		deep[y]=deep[x]+1;
    		dfs_1(y,x);
    		size[x]+=size[y];
    	}
    }
    void dfs_2(re ll x,re ll fa){
    	for(re ll i=pre[x];i;i=nxt[i]){
    		re ll y=to[i];
    		if(y==fa) continue;
    		b[y]=b[x]+sum-2*size[y];
    		dfs_2(y,x);
    	}
    }
    ll dt[MAXN];
    void dfs_3(re ll x,re ll fa){
    	for(re ll i=pre[x];i;i=nxt[i]){
    		re ll y=to[i];
    		if(y==fa) continue;
    		dt[y]=b[y]-b[x];
    		dfs_3(y,x);
    	}
    }
    void dfs_4(re ll x,re ll fa){
    	a[x]=size[x];
    	for(re ll i=pre[x];i;i=nxt[i]){
    		re ll y=to[i];
    		if(y==fa) continue;
    		dfs_4(y,x);
    		a[x]-=size[y];
    	}
    }
    signed main(){
    	scanf("%lld",&t);
    	while(t--){
    		scanf("%lld",&n);
    		for(re ll i=1,u,v;i<n;i++){
    			scanf("%lld%lld",&u,&v);
    			add(u,v),add(v,u);
    		}
    		scanf("%lld",&type);
    		if(type==0){
    			for(re ll i=1;i<=n;i++){
    				scanf("%lld",&a[i]);
    				sum+=a[i];
    				size[i]=a[i];
    			}
    			dfs_1(1,0);
    			for(re ll i=1;i<=n;i++)
    				b[1]+=deep[i]*a[i];
    			dfs_2(1,0);
    			for(re ll i=1;i<=n;i++)
    				printf("%lld ",b[i]);
    			puts("");
    		}else{
    			for(re ll i=1;i<=n;i++){
    				scanf("%lld",&b[i]);
    			}
    			dfs_3(1,0);
    			for(re ll i=1;i<=n;i++)
    				sum+=dt[i];
    			size[1]=(sum+2*b[1])/(n-1);
    			for(re ll i=2;i<=n;i++)
    				size[i]=(size[1]-dt[i])/2;
    			dfs_4(1,0);
    			for(re ll i=1;i<=n;i++)
    				printf("%lld ",a[i]);
    			puts("");
    		}
    		memset(pre,0,sizeof(pre));
    		memset(deep,0,sizeof(deep));
    		memset(size,0,sizeof(size));
    		memset(dt,0,sizeof(dt));
    		memset(a,0,sizeof(a));
    		memset(b,0,sizeof(b));
    		cnt=sum=0;
    	}
    	return 0;
    }
    
    /*
    7
    1 2
    1 3
    2 4
    2 5
    4 6
    4 7
    
    
    10
    5
    1 2
    1 3
    2 4
    2 5
    0
    6 8 7 1 3
    5
    1 2
    1 3
    2 4
    2 5
    1
    23 24 34 47 43
    5
    1 2
    1 3
    2 4
    2 5
    0
    19 2 1 14 3
    5
    1 2
    1 3
    2 4
    2 5
    1
    37 38 74 49 71
    
    4
    1 2
    2 3
    3 4
    0
    5 7 10 8
    
    
    4
    1 2
    2 3
    3 4
    1
    51 31 25 39
    
    6
    1 2
    1 3
    1 4
    2 5
    2 6
    0
    5 7 9 1 3 2
    
    6
    1 2
    1 3
    1 4
    2 5
    2 6
    1
    27 30 36 52 51 53
    */
    

    题:

    3个组合数(CATALAN相关)和一个dp

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #define ll long long
    #define mod 1000000007
    #define MAXN 100005
    using namespace std;
    ll n,type,ans=0,dp[MAXN]={1};
    ll q_pow(ll a,ll b,ll p){
        ll res=1;
        while(b){
            if(b&1) res=(res*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        return res;
    }
    ll fac[MAXN],inv[MAXN];
    void get_fac_and_inv(){
    	fac[0]=fac[1]=inv[0]=inv[1]=1;
    	for(ll i=2;i<=n;i++)
    		fac[i]=fac[i-1]*i%mod;
    	inv[n]=q_pow(fac[n],mod-2,mod);
    	for(ll i=n-1;i>=2;i--)
    		inv[i]=inv[i+1]*(i+1)%mod;
    }
    void dfs(ll now,ll num){
    	if(num==n&&now==0){
    		ans++;
    		if(ans>mod) ans-=mod;
    		//cout<<ans<<endl;
    		return ;
    	}
    	if(num==n&&now!=0) return ;
    	if(abs(now)>(n>>1)) return ;
    	if(abs(now)>(n-num)) return ;
    	dfs(now+1,num+1);
    	dfs(now-1,num+1);
    }
    ll C(ll n,ll m){
    	return fac[n]*inv[m]%mod*inv[n-m]%mod;
    }
    ll CATALAN(ll n){
    	return C(2*n,n)*q_pow(n+1,mod-2,mod)%mod;
    }
    int main(){
    	scanf("%lld%lld",&n,&type);
    	get_fac_and_inv();
    	if(type==0){
    		ll m=n>>1;
    		for(ll i=0;i<=m;i++){
    			ll j=m-i;
    			ans=(ans+(fac[n]*inv[i]%mod*inv[j]%mod*inv[i]%mod*inv[j]%mod)%mod)%mod;
    		}
    		printf("%lld
    ",ans%mod);
    	}
    	if(type==1){
    		ll m=n>>1;
    		ll invm=q_pow(m+1,mod-2,mod);
    		ans=fac[n]*inv[m]%mod*inv[m]%mod*invm%mod;
    		printf("%lld
    ",ans%mod);
    	}
    	if(type==2){
    		dp[1]=dp[0]*4; 
    		for(ll i=2;i<=n/2;i++)
    			for(ll j=1;j<=i;j++)
    				dp[i]=(dp[i]+dp[i-j]%mod*CATALAN(j-1)%mod*4%mod)%mod;
    		printf("%lld
    ",dp[n/2]%mod);
    	}
    	if(type==3){
    		for(ll i=0;i<=n;i+=2)
    			ans=(ans+C(n,i)%mod*CATALAN(i/2)%mod*CATALAN((n-i)/2))%mod;
    		printf("%lld
    ",ans%mod);
    	}
    	return 0;
    }
    
  • 相关阅读:
    周末之个人杂想(十三)
    PowerTip of the DaySorting Multiple Properties
    PowerTip of the DayCreate Remoting Solutions
    PowerTip of the DayAdd Help to Your Functions
    PowerTip of the DayAcessing Function Parameters by Type
    PowerTip of the DayReplace Text in Files
    PowerTip of the DayAdding Extra Information
    PowerTip of the DayPrinting Results
    Win7下IIS 7.5配置SSAS(2008)远程访问
    PowerTip of the DayOpening Current Folder in Explorer
  • 原文地址:https://www.cnblogs.com/Juve/p/11258073.html
Copyright © 2011-2022 走看看