zoukankan      html  css  js  c++  java
  • 牛客网暑期ACM多校训练营(第一场)

    牛客网暑期ACM多校训练营(第一场)


    A. Monotonic Matrix

    考虑0和1的分界线,1和2的分界线,发现问题可以转化为两条不互相穿过的路径的方案数(可重叠),题解的做法就是把一条路径斜着平移,然后就转化为不可重叠了。现在考虑,如何计算从(0,0)道(n,m)不相交不可重叠的方案数,一条从(0,1)出发到达(n-1,m),一条从(1,0)出发到达(n,m-1),将他们乘起来的结果还包含相交的情况,于是再减去从(0,1)到(n,m-1)与(1,0)到(n-1,m)的方案数。

    #include <bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define pb push_back
    #define MP make_pair
    #define fr first
    #define sc second
    typedef long long ll;
    const int N = 1e5 + 7;
    const ll mod = 1e9 + 7;
    using namespace std;
    ll n,m,CC[2005][2005];
    ll C(int n,int m) {return CC[n][m];}
    int main() {
        rep(i,0,2003) CC[i][i]=CC[i][0]=1;
        rep(i,2,2003)rep(j,1,i) CC[i][j] = (CC[i-1][j]+CC[i-1][j-1])%mod;
        while(scanf("%lld%lld",&n,&m)!=EOF) {
            ll ans = ((C(n+m,m)*C(n+m,m))%mod - (C(n+m,m+1)*C(n+m,n+1))%mod+mod)%mod;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
    

    B. Symmetric Matrix

    关键在于把这个矩阵,考虑成一个邻接矩阵,然后发现一个每个点有两条边,且无自环,可以有重边。这张图实际上就是,每个点都属于唯一的一个环,环的大小大于等于2。求这种图的方案数。好像第一类斯特灵数?还得递推搞一下。详见:大佬的推导

    #include <bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define per(i,a,b) for(int i=a;i>=b;--i)
    #define pb push_back
    typedef long long ll;
    const int N = 1e5 + 7;
    using namespace std;
    ll dp[N],n,m;
    int main() {
        dp[1] = 0, dp[2] = 1, dp[3] = 1, dp[4] = 6;
        while(scanf("%lld%lld",&n,&m)!=EOF) {
            if(n<=4) {
                printf("%lld
    ",dp[n]%m);
            }
            else {
                ll M;
                rep(i,5,n)
                    M = 1LL*(i-1LL)*(i-2LL)/2LL,M%=m,
                    dp[i] = (((((i-1)*dp[i-1])%m + ((i-1)*dp[i-2])%m)%m) - (M*dp[i-3])%m + m)%m;
                printf("%lld
    ",dp[n]);
            }
        }
        return 0;
    }
    
    

    D. Two Graphs

    (n!) 枚举与 (G1) 同构的图,在 (G2) 中找到相应的边,如果 (m1) 条边都可以匹配到,则将这种方案中用到的边压成一个64位二进制数,放到set里去重。另一种思路是,出现重算的情况就是,这个同构的图与自身的图相同,即使用这些点的映射,形成的新图与原图一致,这种自同构的情况要从答案中除去。

    #include <bits/stdc++.h>
    typedef unsigned long long ll;
    const ll seed = 31;
    const ll mod = 1e9 + 7;
    inline int read() {
        char c = getchar();int x=0, f=1;
        while(c<'0'||c>'9'){if(c=='-')f = -1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    using namespace std;
    int n,m1,m2,g[11][11],PH[11];
    pair<int,int> p[1111];
    int main() {
        while(scanf("%d%d%d",&n,&m1,&m2)!=EOF) {
            set<int> s;s.clear();
            memset(g,0,sizeof(g));
            for(int i=1;i<=m1;++i) {
                int u=read(),v=read();
                g[u][v] = g[v][u] = 1;
            }
            for(int i=1;i<=m2;++i) {
                int u=read(),v=read();
                p[i] = make_pair(u,v);
            }
            for(int i=1;i<=n;++i) PH[i]=i;
            do{
                ll hs=0,cnt=0;
                for(ll i=1;i<=m2;++i){
                    if(g[PH[p[i].first]][PH[p[i].second]]) {
                        hs |= ((ll)1<<(i-(ll)1));
                        ++cnt;
                    }
                }
                if(cnt == m1)s.insert(hs);
            }while(next_permutation(PH+1,PH+1+n));
            printf("%d
    ",(int)s.size());
        }
        return 0;
    }
    
    

    J. Different Integers

    先写了分块莫队tle,然后写了曼哈顿mst莫队tle,然后分块乱狗tle,t到终场。结束后,加了个快读,分块莫队ac..。还有其他一些做法,其实把整个序列在后边复制一份,不就变成了单个区间询问数字种类的模板题了。(让快读成为习惯。。。为何泥萌常数辣么小

    #include <bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define pb push_back
    #define MP make_pair
    #define fr first
    #define sc second
    typedef long long ll;
    const int N = 1e5 + 7;
    inline int read() {
        char c = getchar();int x=0, f=1;
        while(c<'0'||c>'9'){if(c=='-')f = -1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    using namespace std;
    int n,q,a[N];
    struct pp{int l,r,id,ans;}Q[N];
    int B,belong[N];
    void build() {
        B = sqrt(n);
        for(int i=1; i<=n; i++) belong[i] = (i-1)/B + 1;
    }
    bool cmp(pp a, pp b) {
        if(belong[a.l] == belong[b.l]) return a.r < b.r;
        return belong[a.l] < belong[b.l];
    }
    int sum=0,num[N];
    void update(int p,int d) {
        if(num[a[p]]==1&&d==-1) --sum;
        else if(num[a[p]]==0&&d==1) ++sum;
        num[a[p]]+=d;
    }
    bool cmp1(pp a,pp b) {
        return a.id < b.id;
    }
    int main() {
        while(scanf("%d%d",&n,&q)!=EOF) {
            for(int i=1;i<=n;++i)num[i]=0;
            build();
            for(int i=1;i<=n;++i)a[i]=read();
            for(int i=1;i<=q;++i) {
                Q[i].l=read(),Q[i].r=read();Q[i].id=i;
            }
            sort(Q+1,Q+1+q,cmp);
            int l=0, r=n+1;sum = 0;
            for(int i=1;i<=q;++i) {
                while(r<Q[i].r)update(r,-1),++r;
                while(r>Q[i].r)--r,update(r,1);
                while(l<Q[i].l)++l,update(l,1);
                while(l>Q[i].l)update(l,-1),--l;
                Q[i].ans = sum;
            }
            sort(Q+1,Q+1+q,cmp1);
            for(int i=1;i<=q;++i)printf("%d
    ",Q[i].ans);
        }
        return 0;
    }
    
    
  • 相关阅读:
    in_array()和explode()的使用笔记
    写sql语句连接的时候注意的一个小细节
    在thinkphp框架模板中引用session
    查询数据库所有(某个)表中字段名,数据类型,说明等,导出数据字典
    (委托事件处理)关于多线程执行显示进度条的实例(转)&&线程间操作无效: 从不是创建控件“rtxtEntryNO”的线程访问它。
    判断当前线程所处的状态 (转)以及终止当前线程
    string 字符串的分隔处理与list的相互转换
    C# 动态调用webservice
    C#中的List<string>泛型类示例
    命名空间"system.web"中不存在类型或命名空间名称security"
  • 原文地址:https://www.cnblogs.com/RRRR-wys/p/9339002.html
Copyright © 2011-2022 走看看