zoukankan      html  css  js  c++  java
  • 18.10.17队测

    T1 :

    题意简化 : 给出(n)个区间和(m)个点,问一个区间和一个点匹配,最多可以匹配多少个点。 其中,(nleq 2e5,mleq2e5,a[i]leq1e9).

    贪心,给点排序,然后把区间以右端点为关键字用一个set维护,每次对于一个点取右端点大于且最靠近这个点的区间。

    #include<bits/stdc++.h>
    using namespace std;
    #define read(x) scanf("%d",&x)
    #define write(x) printf("%d
    ",x)
    #define maxn 200005
    #define inf 1e9
    int n,m,a[maxn],ans;
    struct data{int x,y;}c[maxn];
    multiset<int > s;
    multiset<int> :: iterator x;
    bool cmp(data a,data b){return (a.y==b.y&&a.x<b.x)||a.y<b.y;}
    int main(){
        read(n),read(m);
        for(int i=1;i<=m;i++) read(c[i].x),read(c[i].y);
        for(int i=1;i<=n;i++) read(a[i]),s.insert(a[i]);
        sort(c+1,c+m+1,cmp);s.insert(inf);
        for(int i=1;i<=m;i++){
        	x=s.lower_bound(c[i].x);
        	if((*x)<=c[i].y&&x!=s.end()) ans++,s.erase(x);
        }
        write(ans);
        return 0;
    }
    

    T2 :

    题意简化: 问随机的树在模(p)的期望深度。构造方法:每次将第(i)个点在([1,i-1])中随机的选一个点作为父亲。

    其中:(nleq 200,pleq1e9+7),且(p)为质数。

    对于(50\%)的数据,(nleq20),可以状压dp,设(f[sta])为状态为(sta)的方案数。

    对于状态的记录,首先可以想到:第(i)位为(h)表示第(i)个点的高度是(h),但是这样不方便我们记录,所以将这个数列排序后差分一下,可以得到一个(01)串,然后状态转移可以类似的由(1001001)转移到(10001001)(10010001)等。

    对于所有数据,显然不能用上面的指数级dp。记(dp[i][j])表示(i)个结点的森林深度为(j)的概率。

    [dp[i][j]=dp[i-1][j-1]*(j-1)*inv[i]+dp[i-1][j]*(i-j)*inv[i] ]

    其中,由于一个点也是一棵树,可以单独存在,所以要除以(i)而不是(i-1)

    然后记(f[i][j])表示i个点的树深度小于等于j的概率,(g[i][j])为i个点的森林深度小于等于j的概率。

    首先,显然(f[i ][ j ]=g[i-1][j-1]) ,因为可以设一个根节点连向森林里的所有树,然后深度(+1).然后,

    [g[i][j]=sum_{k=1}^if[k][j]*g[i-k][j]*dp[i][k] ]

    这个也比较显然,然后最后对于深度为i的概率可以由(f[n][i]-f[n][i-1])得到。

    初值以及小细节什么的看代码吧。。说实话这个dp是真的难想到。。

    #pragma GCC optimize(3)
    #include<cstdio>
    #define int long long
    #define max(a,b) (a<b?b:a)
    #define min(a,b) (a<b?a:b)
    #define swap(x,y) x^=y^=x^=y
    #define isdigit(ch) (ch>='0'&&ch<='9')
    #define abs(x) (x<0?-x:x)
    #define base 2333
    #define pb push_back
    inline void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);x*=f;
    }
    inline void print(int x) {
        if(x<0) putchar('-'),x=-x;
        if(x>9) print(x/10);
        putchar(x%10+'0');
    }
    inline void write(int x) {print(x);puts("");}
    #define maxn 230
    int dp[maxn][maxn],g[maxn][maxn],f[maxn][maxn],n,p,inv[maxn];
    signed main() {
        read(n),read(p);inv[1]=1;inv[0]=1;
        for(int i=2;i<=n;i++) inv[i]=(p-p/i)*inv[p%i]%p;
        dp[1][1]=1;
        for(int i=2;i<=n;i++)
        for(int j=1;j<=n;j++)
            dp[i][j]=(dp[i-1][j-1]*(j-1)%p*inv[i]%p+dp[i-1][j]*(i-j)%p*inv[i]%p)%p;
        for(int i=0;i<=n;i++) f[1][i]=g[1][i]=f[0][i]=g[0][i]=1;g[1][0]=0;
        for(int i=2;i<=n;i++)
        for(int j=1;j<=n;j++) {
            f[i][j]=g[i-1][j-1];
            for(int k=1;k<=i;k++) (g[i][j]+=f[k][j]*g[i-k][j]%p*dp[i][k])%=p;
        }
        int ans=0;
        for(int i=1;i<=n;i++) ans=(ans+i*(f[n][i]-f[n][i-1]))%p;
        write((ans-1+p)%p);
        return 0;
    }
    

    T3 :

    题意简述 :

    给出一颗有编号的树,每次选择一个区间的编号,问有多少个联通块。

    其中(nleq 2e5,qleq2e5).

    (nleq2000)暴力有50分。。

    其实这题和树一点关系也没有。。。

    可以发现,对于一个区间([l,r]),先令(ans=r-l+1),当且仅当一条边(<u,v>(u<v)) 满足(lleq u,vleq r)时,才可以令(ans--).

    于是这就变成了一个基本的二维偏序问题。。用个树状数组或者什么的维护下就好了。

    #pragma GCC optimize(3)
    #include<cstdio>
    #include<algorithm>
    using std :: sort;
    #define max(a,b) (a<b?b:a)
    #define min(a,b) (a<b?a:b)
    #define swap(x,y) x^=y^=x^=y
    #define isdigit(ch) (ch>='0'&&ch<='9')
    #define abs(x) (x<0?-x:x)
    #define pb push_back
    const int mod = 1e9+7;
    inline void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);x*=f;
    }
    inline void print(int x) {
        if(x<0) putchar('-'),x=-x;
        if(x>9) print(x/10);
        putchar(x%10+'0');
    }
    inline void write(int x) {print(x);puts("");}
    #define maxn 2000050
     
    int n,q;
    struct node {int l,r,x,ans,id;}a[maxn];
    struct binary_index_tree {
        int tree[maxn];
        void modify(int x,int v) {for(int i=x;i<=n;i+=i&-i) tree[i]+=v;}
        int query(int x,int ans=0) {for(int i=x;i;i-=i&-i) ans+=tree[i];return ans;}
    }T;
    int cmp_l(node aa,node b) {return aa.l<b.l||(aa.l==b.l&&aa.r>b.r)||(aa.l==b.l&&aa.r==b.r&&aa.x>b.x);}
    int cmp_id(node aa,node b) {return aa.id<b.id;}
     
    int main() {
        read(n),read(q);
        for(int i=1;i<n;i++) {read(a[i].l),read(a[i].r),a[i].x=1;if(a[i].l>a[i].r) swap(a[i].r,a[i].l);}
        for(int i=n;i<=n+q-1;i++) read(a[i].l),read(a[i].r),a[i].x=2,a[i].ans=a[i].r-a[i].l+1,a[i].id=i;
        sort(a+1,a+n+q,cmp_l);
        for(int i=n+q-1;i;i--) {
        if(a[i].x==1) T.modify(a[i].r,1);
        else a[i].ans-=T.query(a[i].r);
        }
        sort(a+1,a+n+q,cmp_id);
        for(int i=n;i<n+q;i++) write(a[i].ans);
        return 0;
    }
    
  • 相关阅读:
    Maven学习总结(二)——Maven项目构建过程练习
    使用Maven搭建Struts2框架的开发环境
    使用Maven编译项目遇到——“maven编码gbk的不可映射字符”解决办法
    MyEclipse10安装Log4E插件
    大数据以及Hadoop相关概念介绍
    Servlet3.0学习总结(四)——使用注解标注监听器(Listener)
    Servlet3.0学习总结(三)——基于Servlet3.0的文件上传
    Servlet3.0学习总结(二)——使用注解标注过滤器(Filter)
    Servlet3.0学习总结(一)——使用注解标注Servlet
    使用kaptcha生成验证码
  • 原文地址:https://www.cnblogs.com/hbyer/p/9806905.html
Copyright © 2011-2022 走看看