• 简单题 题解


    题目

    容易题

    昨天考试考了这道 容易题 ,不知道怎么想的,打了个DP,居然拿了70,先定义 dis[ i ] [ j ] 表示最后是第 i 行,最后一个数是 j 的结果,vis[ i ] [ j ]表示第i行j是否可选,然后想到枚举到第k,然后后面的数其实是可以用乘法分配律结合,所以转移方程就是

    [dis[ i ] [ j ] = sumlimits_{k=1}^{n} {dis[ i - 1 ][k] imes j } ( vis[ i ] [ j ] = 0 ) ]

    然后前缀和优化从($ n^3 ()优化到() n^2 $),最后答案就是sum[ m ] ,这样就可以拿到 70 分 的好成绩

    (Code)

    for(int i=1,x,y;i<=k;++i){
    	x=read();y=read();
    	vis[x][y]=1;
    }
    for(int i=1;i<=n;++i){
    	if(vis[1][i])continue;
    	dis[1][i]=i;sum[1]=(sum[1]+i)%mod;
    }
    for(int i=2;i<=m;++i){
    	for(int j=1;j<=n;++j){
    		if(vis[i][j])continue;
    		dis[i][j]=(dis[i][j]+j*sum[i-1]%mod)%mod;
    	}
    	for(int j=1;j<=n;++j)
    		sum[i]=(sum[i]+dis[i][j])%mod;
    }
    

    现在再想一下,上面的式子其实就是

    [sum[ i ] = sumlimits_{k=1}^{n} dis[i][k] ]

    然后又发现

    [dis[i][k] = sumlimits_{j=1}^{n} k imes sum[i-1] ]

    最后可以得出递推式

    [sum[i] = sum[i-1] imes sumlimits_{j=1}^{n}j(vis[i-1][j]=0) ]

    于是这就是一个真的简单题了,最后结果就是

    [ans = prodlimits_{i=1}^{n} sumlimits_{j=1}^{n}j ]

    这就是没有限制的式子,如果有限制的话只需要在乘的时候减去即可
    比如(n == 2,m == 3)时,$ k==2 $, ((1,1),(2,2))不能选,(ans=(1) * (2) * (1+2))
    然后看到 n 到了 (1e9), k 只有 (1e5)所以从 k 入手,先用结构体存起来k个限制,排一下序,减去,剩下的跑一个快速幂即可,同时要注意去重,很多大佬用是用map去重,一开始看的迷迷糊糊的(可能是我太菜了),于是我用来一个STL的神奇函数unique,这个函数可以做到去重。
    ,然后利用map映射记录每个被修改的x对应的值,乘进去即可。最后提一点,因为 n 太大,用累加直接 T 飞,一定要用等差数列求和算(死了3次才的出的宝贵经验,应该不会有人和我一样傻吧

    (Code)

    #include <bits/stdc++.h>
    using namespace std;
    #define gc getchar()
    const long long mod=1e9+7;
    long long n,m,k,cnt;
    long long ans=1,s;
    long long mp[1000000+10];
    map<int,long long> ma;
    struct gdx{
    	long long x,y;
    	friend bool operator < (const gdx &A,const gdx &B){
    		return A.x < B.x;
    	}
    	friend bool operator == (const gdx &A,const gdx &B){
    		return (A.x==B.x&&A.y==B.y);
    	}
    }a[1000000+10];
    
    inline int read(){
    	int r=0,l=1;char ch=gc;
    	while(!isdigit(ch)){if(ch=='-')l=-1;ch=gc;}
    	while(isdigit(ch)){r=(r<<3)+(r<<1)+ch-'0';ch=gc;}
    	return r*l;
    }
    
    inline long long ksm(long long x,long long y){
    	long long ans=1;
    	while(y){
    		if(y&1)ans=ans*x%mod;
    		y>>=1;x=x*x%mod;
    	}
    	return ans;
    }
    
    int main(){
    	freopen("easy.in","r",stdin);
    	freopen("easy.out","w",stdout);
    	n=read();m=read();k=read();
    	s=n*(n+1)/2%mod;
    	for(int i=1,x,y;i<=k;++i)
    		a[i].x=read(),a[i].y=read();
    	sort(a+1,a+k+1);
    	int p=unique(a+1,a+k+1)-a;p--;
    	for(int i=1,l=0;i<=p;++i){
    		if(l!=a[i].x){
    			mp[++cnt]=a[i].x;
    			ma[a[i].x]=s;l=a[i].x;
    		}
    		ma[a[i].x]=(ma[a[i].x]-a[i].y+mod)%mod;
    	}
    	for(int i=1;i<=cnt;++i)ans=ans*ma[mp[i]]%mod;
    	ans=ans*ksm(s,m-cnt)%mod;
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    进程(第三部分)
    02_jni_hello_c函数介绍
    01_ndk目录介绍
    00_前情回顾
    06_锅炉压力案例_progressbar实现
    05_锅炉压力案例_java实现
    ASP.NET MVC的过滤器笔记
    ASP.NET MVC的过滤器笔记
    ASP.NET MVC的过滤器笔记
    ASP.NET MVC的过滤器笔记
  • 原文地址:https://www.cnblogs.com/gdxzq/p/13790021.html
Copyright © 2020-2023  润新知