zoukankan      html  css  js  c++  java
  • 「CodeM」排列

    传送门

    Description

    (n) 个二维点 ((a_i,b_i)),询问有多少种排列 (p)(答案对 (10^9+7) 取模)使得执行以下伪代码后留下的点是 (i),即最后 ( ext{saved} = i)

    saved = p[1]
    for x from 2 to n
        if a[p[x]] >= a[saved] and b[p[x]] >= b[saved]
            saved = p[x]
    

    保证 (a)(b) 分别为一个排列。

    Solution 

    对于一个点,如果不存在两维都比他大的点,那么它有解

    考虑(saved)总共存储过的值,设为(A_1,...,A_k)

    那么,在所有横纵坐标都比(A_i)的大的点中,(A_{i+1})一定是最早出现的

    (num[i])表示有(num[i])个点一定不能排在(i)之前((i)自己也算),特别的(num[p_1]=n)

    所以这样的排列(指依次停留在(A_1,...,A_k))会有(frac{n!}{prod_{i=1}^k num[A_i]})

    简化为(frac{(n-1)!}{prod_{i=1}^{k-1}b[A_i]})(b[i])表示横纵坐标都比(i)号点大的点的个数

    可以(dp)求解,需要做个二维求和,可以先对一维排序,第二维用树状数组维护即可

    Code 

    #include<bits/stdc++.h>
    #define ll long long
    #define dbg1(x) cerr<<#x<<"="<<(x)<<" "
    #define dbg2(x) cerr<<#x<<"="<<(x)<<"
    "
    #define dbg3(x) cerr<<#x<<"
    "
    using namespace std;
    #define reg register
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    const int MN=1e5+5,P=1e9+7;
    int Mul(int x,int y){return (1ll*x*y)%P;}
    int Add(int x,int y){return (x+y)%P;}
    int N,inv[MN];
    struct d{int x,y,id;}a[MN];
    int T[MN],b[MN],ans[MN];
    void C(int x,int y){for(;x<=N;x+=(x&-x))T[x]=Add(T[x],y);}
    int G(int x){int r=0;for(;x;x-=(x&-x))r=Add(r,T[x]);return r;}
    bool cmp(d x,d y){return (x.x!=y.x)?(x.x<y.x):(x.y<y.y);}
    int main()
    {
    	N=read();reg int i;
    	for(inv[0]=inv[1]=1,i=2;i<=N;++i)inv[i]=Mul(inv[P%i],(P-P/i));
    	for(i=1;i<=N;++i)a[i].x=read(),a[i].y=read(),a[i].id=i;
    	std::sort(a+1,a+N+1,cmp);
    	for(i=N;i;--i)b[i]=N-i-G(a[i].y),C(a[i].y,1);
    	memset(T,0,sizeof T);C(1,1);
    	for(i=1;i<=N;++i)
    	{
    		int V=G(a[i].y);
    		if(b[i])C(a[i].y,Mul(V,inv[b[i]]));
    		else ans[a[i].id]=V;
    	}
    	int fac=1;for(i=1;i<N;++i)fac=Mul(fac,i);
    	for(i=1;i<=N;++i)printf("%d
    ",Mul(fac,ans[i]));
    	return 0;
    } 
    


    Blog来自PaperCloud,未经允许,请勿转载,TKS!

  • 相关阅读:
    JAVA过滤器(Filter)与拦截器(Interceptor)区别及关系
    原创:shiro 入门配置三步骤
    Shiro笔记(三)----Shiro配置文件ini详解
    搭建用Selenium模拟chrome浏览器运行环境,为模拟登陆做准备
    IDEA编译时,idea java: 找不到符号
    mybatis分页插件 pageHelper 在dao、 service , 各模块单元测试及Web层配置使用
    CF 336494 B. Divisor Subtraction
    【动态规划】DP状态机(UP20210815)
    DP数字三角形变形——方格取数
    hold sb at bay
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/11662829.html
Copyright © 2011-2022 走看看