• 慈溪中学摸底测试


    A 求组合数

    首先咱一开始并没有看到 Q 的数据范围,并且子任务表格里还有一堆 none (???)

    于是整个机房都打算阿了出题人

    后来滚回来看的时候 bug 基本都修好了,于是开始挠头发(这个数据范围真是要人命啊 Q 居然可以到 2e9 ...)

    但后来看到了这个 m 的范围比较小,于是估计这道题就是利用 m 比较小的性质来做的

    于是列一下 (C_n^m) 的公式:

    [C_n^m ={n!over m!·(n-m)!} ]

    并没有什么软用...然后用下降幂表示一下:

    [C_n^m ={n^{underline{m}}over m!} ]

    说人话就是:

    [C_n^m ={n*(n-1)*···*(n-m+1)over m*(m-1)*···*1} ]

    发现上下都只有 (m) 项(挠头)

    于是想想如果 mod 为质数怎么做: 咱可以 (O(m)) 得去得到这个公式上面和下面两个部分的值,然后 (O(log ~mod)) 蒙哥马利一下就可以得到答案了 【汗

    然后咱考虑 mod 不是质数的情况,这个时候咱需要对上下两部分的 m 个数进行质因子分解,这是 (sqrt n) 的复杂度,但咱可以用人类智慧优化到 (sqrt nover log ~n) ,具体康代码(好吧不就是普通的欧拉筛么)...

    然后咱把上下两部分的质因子分别加起来,上面的每个质因子 (p_i) 的次数 (k_{i1}) 减去下面质因子的次数 (k_{i2}) ,然后每个质因子快速幂一下就好了(这个复杂度好像是 $sqrt n ~loglog ~n $ 级别的 )

    但是咱发现太大的质因子存不下呢...那咱就把这些太大的质因子(超过 (sqrt n) 的)用 map 去存就好了(复杂度大概是 (m ~log ~m) ...?最后遍历时候的复杂度也不高(应该...)

    然后咱本地测了最大数据... T 飞上天(顿时懵逼

    懵逼一会儿之后开始补救,大概就是对于 mod 是质数的情况进行了特判...少了 (sqrt nover log ~n) 的复杂度...

    最后就是一边自闭一边把代码交上去准备 T 飞了...

    【结果最后数据特别友好,真是气人啊,浪费感情...

    // by Judge
    #pragma GCC optimize("Ofast")
    #include <bits/stdc++.h>
    #define Rg register
    #define fp(i, a, b) for (Rg int i = (a), I = (b) + 1; i < I; ++i)
    #define fd(i, a, b) for (Rg int i = (a), I = (b)-1; i > I; --i)
    #define ll long long
    using namespace std;
    const int M = 5e4 + 3;
    typedef int arr[M];
    #ifndef Judge
    #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
    #endif
    char buf[1 << 21], *p1 = buf, *p2 = buf;
    inline bool cmax(int& a, int b) { return a < b ? a = b, 1 : 0; }
    inline bool cmin(int& a, int b) { return a > b ? a = b, 1 : 0; }
    inline int read() {
        int x = 0, f = 1;
        char c = getchar();
        for (; !isdigit(c); c = getchar())
            if (c == '-')
                f = -1;
        for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
        return x * f;
    }
    int n, m, mod, id1[M];
    map<int, int> id2;
    inline int mul(int x, int y) { return 1ll * x * y % mod; }
    inline int qpow(int x, int p) {
        Rg int s = 1;
        for (; p; p >>= 1, x = mul(x, x))
            if (p & 1)
                s = mul(s, x);
        return s;
    }
    int cnt, p[M], v[M];
    inline void prep(int n) {
        fp(i, 2, n) {
            if (!v[i])
                p[++cnt] = i, v[p[cnt]] = cnt;
            for (Rg int j = 1; j <= cnt && i * p[j] <= n; ++j) {
                v[i * p[j]] = 1;
                if (!(i % p[j]))
                    break;
            }
        }
    }
    inline void add(int x, int V) {
        fp(i, 1, cnt) {
            if (p[i] * p[i] > x)
                break;
            while (!(x % p[i])) id1[i] += V, x /= p[i];
        }
        if (x > 1) {
            if (x > p[cnt])
                id2[x] += V;
            else
                id1[v[x]] += V;
        }
    }
    #define IT map<int, int>::iterator
    inline int solv() {
        Rg int ans = 1;
        fp(i, 1, cnt) if (id1[i]) ans = mul(ans, qpow(p[i], id1[i]));
        for (IT it = id2.begin(); it != id2.end(); ++it) ans = mul(ans, qpow(it->first, it->second));
        return ans;
    }
    inline bool isprime(int x) {
        fp(i, 1, cnt) {
            if (p[i] * p[i] > x)
                return 1;
            if (!(x % p[i]))
                return 0;
        }
        return 1;
    }
    inline void solv0() {
        Rg int p = 1, q = 1;
        fp(i, 1, m) p = mul(p, n - i + 1), q = mul(q, i);
        printf("%d
    ", mul(p, qpow(q, mod - 2)));
    }
    int main() {
        int T = read();
        prep(5e4);
        while (T--) {
            n = read(), m = read(), mod = read();
            if (isprime(mod)) {
                solv0();
                continue;
            }
            memset(id1, 0, sizeof id1), id2.clear();
            fp(i, 1, m) add(n - i + 1, 1), add(i, -1);
            printf("%d
    ", solv());
        }
        return 0;
    }
    

    B 铺地板

    比赛的时候咱可是放过话的:“网络流这种东西 CSP 怎么可能会考,你见过 NOIP 考过 wll 么?他要敢考咱就敢爆零!” 于是咱并没有黑白染色冷静一下并且华丽爆炸...

    给个乱打的代码(没有交过 因为交不了

    评价:有一定参考价值,若出锅请轻喷...

    //by Judge
    #include<bits/stdc++.h>
    #define Rg register
    #define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(Rg int i=head[u],v=e[i].to;i;v=e[i=e[i].nxt].to)
    #define open(S) freopen(S".in","r",stdin),freopen(S".out","w",stdout)
    #define ll long long
    using namespace std;
    const int M=65;
    typedef int arr[M][M];
    typedef int ARR[M*M];
    const int h[5]={0,-1,1,0,0},l[5]={0,0,0,-1,1};
    #ifndef Judge
    #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    #endif
    char buf[1<<21],*p1=buf,*p2=buf;
    inline int read(){ int x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
    } inline int cread(){ char c=getchar();
        while(c!='.'&&c!='#') c=getchar(); return c=='.';
    } int n,cnt,tim,pat,ans; ARR head,used,Get; arr a,id;
    struct Edge{ int to,nxt; }e[M*M<<2];
    inline void add(int u,int v){
        e[++pat]=(Edge){v,head[u]},head[u]=pat;
    }
    inline int calc(int x,int y){
        return a[x-1][y]+a[x][y-1]+a[x+1][y]+a[x][y+1];
    }
    bool find(int u){
        go(u) if(used[v]<tim){ used[v]=tim;
            if(!Get[v]||find(Get[v])) return Get[v]=u;
        } return 0;
    }
    int main(){ int T=read();
        while(T--){
            n=read(),ans=pat=cnt=tim=0;
            memset(head,0,sizeof head);
            memset(used,0,sizeof used);
            memset(Get,0,sizeof Get);
            fp(i,1,n+1) a[i][n+1]=a[n+1][i]=0;
            fp(i,1,n) fp(j,1,n){ a[i][j]=cread();
                id[i][j]=a[i][j]?++cnt:0;
            }
            fp(x,1,n) fp(y,1,n) fp(i,1,4) if(a[x][y]){
                Rg int dx=x+h[i],dy=y+l[i];
                if(a[dx][dy]) add(id[x][y],id[dx][dy]);
            }
            fp(x,1,n) fp(y,1,n) if(a[x][y]&&((x+y)&1))
                ++tim,ans+=find(id[x][y]);
            printf("%d
    ",n*n-ans*2);
        } return 0;
    }
    

    C 军训队列

    一开始以为是斜优 dp 想着这出题人也是够毒瘤(虽说也不算太超纲...吧?),结果一看数据范围 500 , (n^3) 喜 dp (斜优 × 暴力 √ )

    // by Judge
    #pragma GCC optimize("Ofast")
    #include <bits/stdc++.h>
    #define Rg register
    #define fp(i, a, b) for (Rg int i = (a), I = (b) + 1; i < I; ++i)
    #define fd(i, a, b) for (Rg int i = (a), I = (b)-1; i > I; --i)
    #define ll long long
    using namespace std;
    const int M = 503;
    typedef int arr[M];
    #ifndef Judge
    #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
    #endif
    char buf[1 << 21], *p1 = buf, *p2 = buf;
    inline int read() {
        int x = 0, f = 1;
        char c = getchar();
        for (; !isdigit(c); c = getchar())
            if (c == '-')
                f = -1;
        for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
        return x * f;
    }
    int n, K, a[M], f[M][M];
    inline int Min(int x, int y) { return x < y ? x : y; }
    int main() {
        n = read(), K = read();
        if (K >= n)
            return !printf("0
    ");
        fp(i, 1, n) a[i] = read();
        sort(a + 1, a + 1 + n), memset(f, 0x3f, sizeof f), f[0][0] = 0;
        fp(i, 1, n) fp(j, 1, Min(i, K)) fp(k, 0, i - 1) f[i][j] =
            Min(f[i][j], f[k][j - 1] + (a[i] - a[k + 1]) * (a[i] - a[k + 1]));
        return !printf("%d
    ", f[n][K]);
    }
    
  • 相关阅读:
    Java实现“睡排序”——线程池Executors的使用
    浅谈HashMap与线程安全 (JDK1.8)
    Ubuntu 16 Java Develop环境快速搭建
    Spring Boot在反序列化过程中:jackson.databind.exc.InvalidDefinitionException cannot deserialize from Object value
    Java 8 – Map排序
    vue指令优化网络图片加载速度
    如何实现小于12px的字体效果
    两种以上方式实现已知或者未知宽度的垂直水平居中
    C# winform窗体间传值(使用委托或事件)
    C#栈Stack的使用
  • 原文地址:https://www.cnblogs.com/Judge/p/11568622.html
Copyright © 2020-2023  润新知