• 2018年湖南省第十四届大学生计算机程序设计竞赛


    题目链接

    传送门

    题目

    A题

    思路

    签到。

    代码

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    using namespace std;
     
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
     
    #define fi first
    #define se second
    #define lson (rt<<1)
    #define rson (rt<<1|1)
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
     
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 200000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
     
    int n;
     
    int main() {
        scanf("%d", &n);
        printf("ooo");
        for(int i = 1; i <= n; ++i) printf(".");
        printf("ooo");
        for(int i = 1; i <= n; ++i) printf(".");
        printf("ooo");
        for(int i = 1; i <= n; ++i) printf(".");
        printf("ooo
    ");
        printf("..o");
        for(int i = 1; i <= n; ++i) printf(".");
        printf("o.o");
        for(int i = 1; i <= n; ++i) printf(".");
        printf(".o.");
        for(int i = 1; i <= n; ++i) printf(".");
        printf("o.o
    ");
        printf("ooo");
        for(int i = 1; i <= n; ++i) printf(".");
        printf("o.o");
        for(int i = 1; i <= n; ++i) printf(".");
        printf(".o.");
        for(int i = 1; i <= n; ++i) printf(".");
        printf("ooo
    ");
        printf("o..");
        for(int i = 1; i <= n; ++i) printf(".");
        printf("o.o");
        for(int i = 1; i <= n; ++i) printf(".");
        printf(".o.");
        for(int i = 1; i <= n; ++i) printf(".");
        printf("o.o
    ");
        printf("ooo");
        for(int i = 1; i <= n; ++i) printf(".");
        printf("ooo");
        for(int i = 1; i <= n; ++i) printf(".");
        printf("ooo");
        for(int i = 1; i <= n; ++i) printf(".");
        printf("ooo
    ");
        return 0;
    }
    

    B题

    思路

    打表找规律。

    代码

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
     
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
     
    #define fi first
    #define se second
    #define lson (rt<<1)
    #define rson (rt<<1|1)
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("/home/dillonh/CLionProjects/Dillonh/in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
     
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 200000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
     
    int n, m;
    int C[4007][2007];
     
    int main() {
    #ifndef ONLINE_JUDGE
        FIN;
    #endif
        for(int i = 0; i <= 4000; ++i) {
            C[i][0] = 1;
            for(int j = 1; j <= min(i, 2000); ++j) {
                C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mod;
            }
        }
        while(~scanf("%d%d", &n, &m)) {
            printf("%lld
    ", 1LL * (C[n+m][m] - 1) * (C[n+m][m] - 1) % mod);
        }
        return 0;
    }
    

    C题

    思路

    看样例猜。

    代码

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
     
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
     
    #define fi first
    #define se second
    #define lson (rt<<1)
    #define rson (rt<<1|1)
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("/home/dillonh/CLionProjects/Dillonh/in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
     
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 200000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
     
    int h, c;
     
    int main() {
        while(~scanf("%d%d", &h, &c)) {
            printf("%d
    ", h > c ? h : c + 1);
        }
        return 0;
    }
    

    E题

    思路

    初始时联通快有(n imes m)个,由于在每次进行操作之后重新数联通块比较复杂,因此我们可以将思路转换一下,变成每次操作后联通块减少了(x),那么答案就是(n imes m-x)

    我们可以发现每次增加一条新的横线(前面没有对这一行进行操作)后联通块减少了(m-1)个,每次增加一条竖线后联通块减少了(n-1)个。

    我们假设横线数目为(h),竖线数目为(w),那么当只有横线时答案为(n imes m-h imes(m-1)),当只有竖线时答案为(n imes m-w imes(n-1))。当既有横线又有竖线时需要稍微容斥一下,因为对于交叉点我们会重复减掉,因此需要加回来,被重复减掉部分为((h-1) imes(w-1)),此时答案为(n imes m-h imes(m-1)-w imes(n-1)+(h-1) imes(w-1))

    注意同一行被操作多次只能被算一次,因此我们可以考虑用左闭右开线段树来维护。

    代码

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    using namespace std;
     
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
     
    #define fi first
    #define se second
    #define lson (rt<<1)
    #define rson (rt<<1|1)
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
     
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 200000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
     
    bool lazy[3][maxn<<2];
    int n, m, q, cnt;
    int op[maxn], l[maxn], r[maxn], sum[3][maxn<<2], num[maxn*2];
     
    void push_down(int rt, int l, int r, int id) {
        if(!lazy[id][rt]) return;
        lazy[id][rt] = 0;
        lazy[id][lson] = lazy[id][rson] = 1;
        int mid = (l + r) >> 1;
        sum[id][lson] = num[mid+1] - num[l];
        sum[id][rson] = num[r+1] - num[mid+1];
    }
     
    void push_up(int rt, int id) {
        sum[id][rt] = sum[id][lson] + sum[id][rson];
    }
     
    void build(int rt, int l, int r) {
        for(int i = 0; i < 2; ++i) sum[i][rt] = 0, lazy[i][rt] = false;
        if(l == r) return;
        int mid = (l + r) >> 1;
        build(lson, l, mid), build(rson, mid + 1, r);
    }
     
    void update(int rt, int l, int r, int L, int R, int id) {
        if(l == L && r == R) {
            sum[id][rt] = num[R+1] - num[L];
            lazy[id][rt] = true;
            return;
        }
        push_down(rt, l, r, id);
        int mid = (l + r) >> 1;
        if(R <= mid) update(lson, l, mid, L, R, id);
        else if(L > mid) update(rson, mid + 1, r, L, R, id);
        else {
            update(lson, l, mid, L, mid, id);
            update(rson, mid + 1, r, mid + 1, R, id);
        }
        push_up(rt, id);
    }
     
    int getnum(int x) {
        return lower_bound(num + 1, num + cnt + 1, x) - num;
    }
     
    int main() {
    #ifndef ONLINE_JUDGE
        FIN;
    #endif
        while(~scanf("%d%d%d", &n, &m, &q)) {
            cnt = 0;
            for(int i = 1; i <= q; ++i) {
                scanf("%d%d%d", &op[i], &l[i], &r[i]);
                num[++cnt] = l[i], num[++cnt] = r[i] + 1;
            }
            sort(num + 1, num + cnt + 1);
            cnt = unique(num + 1, num + cnt + 1) - num - 1;
            build(1, 1, cnt);
            for(int i = 1; i <= q; ++i) {
                l[i] = getnum(l[i]), r[i] = getnum(r[i]+1);
                if(op[i] == 1) {
                    update(1, 1, cnt, l[i], r[i]-1, 0);
                } else {
                    update(1, 1, cnt, l[i], r[i]-1, 1);
                }
                // printf("[%d %d]
    ", sum[0][1], sum[1][1]);
                LL ans = 1LL * n * m - 1LL * sum[0][1] * (m - 1) - 1LL * sum[1][1] * (n - 1);
                if(sum[0][1] && sum[1][1]) ans += 1LL * (sum[0][1] - 1) * (sum[1][1] - 1);
                printf("%lld
    ", ans);
            }
        }
        return 0;
    }
    

    H题

    思路

    由于查询时保证(r-lleq 2),因此我们可以用三个树状数组分别存下以(i)为左端点,区间长度为(0,1,2)的区间被哪些区间覆盖过。

    插入时对于([l,r])的每个数作为左端点区间长度为(0)的均有被覆盖,([l,r-1])为左端点区间长度为(1)的均有被覆盖,([l,r-2])为左端点区间长度为(2)的均有被覆盖,分别进行(update)即可。

    代码

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
     
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
     
    #define fi first
    #define se second
    #define lson (rt<<1)
    #define rson (rt<<1|1)
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("/home/dillonh/CLionProjects/Dillonh/in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
     
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 100000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
     
    inline int read() {
        int f = 0, x = 0;
        char ch = getchar();
        while (ch < '0' || ch > '9') f |= (ch == '-'), ch = getchar();
        while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
        return x = f ? -x : x;
    }
     
    int n, q, op, l, r;
    int tree[5][maxn];
     
    void bit_add(int x, int id, int val) {
        while(x <= n) {
            tree[id][x] += val;
            x += lowbit(x);
        }
    }
     
    int bit_query(int x, int id) {
        int ans = 0;
        while(x) {
            ans += tree[id][x];
            x -= lowbit(x);
        }
        return ans;
    }
     
    int main() {
    #ifndef ONLINE_JUDGE
        FIN;
    #endif
        while(~scanf("%d%d", &n, &q)) {
            for(int i = 0; i <= 2; ++i) {
                for(int j = 0; j <= n; ++j) tree[i][j] = 0;
            }
            while(q--) {
                op = read(), l = read(), r = read();
                if(op == 1) {
                    bit_add(l, 0, 1);
                    bit_add(r + 1, 0, -1);
                    if(l <= r - 1) {
                        bit_add(l, 1, 1);
                        bit_add(r, 1, -1);
                    }
                    if(l <= r - 2) {
                        bit_add(l, 2, 1);
                        bit_add(r - 1, 2, -1);
                    }
                } else {
                    printf("%d
    ", bit_query(l, r-l));
                }
            }
        }
        return 0;
    }
    

    J题

    思路

    我们考虑当前(dfs)到结点(u),从(1)(u)的父亲结点得到的答案为(sum),那么(f_u=sum+u)的贡献。

    (a[u])(1)(u)这条链上是第一次出现时,此时(u)的贡献为这条链上不同数的个数;

    (a[u])是第二次出现时,此时(u)的贡献为上一次(a[u])出现位置到(u)的路径上不同数的个数(+1),这个(1)表示的有序对是((a[u],a[u]))

    (a[u])出现次数大于(2)时,此时(u)的贡献为上一次(a[u])出现位置到(u)的路径上不同数的个数。

    在回溯的时候记得清除(u)造成的影响。

    代码

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
     
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
     
    #define fi first
    #define se second
    #define lson (rt<<1)
    #define rson (rt<<1|1)
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("/home/dillonh/CLionProjects/Dillonh/in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
     
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 200000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
     
    int ans[maxn], sum;
    int n, u, tot, cnt;
    int head[maxn], a[maxn], vis[maxn], lst[maxn];
     
    struct edge {
        int v, next;
    }ed[maxn*2];
     
    void add(int u, int v) {
        ed[tot].v = v;
        ed[tot].next = head[u];
        head[u] = tot++;
    }
     
    void dfs(int u) {
        int tmp = 0;
        if(!vis[a[u]]) tmp = cnt, ++cnt;
        else if(vis[a[u]] == 1) tmp = cnt - lst[a[u]] + 1;
        else tmp = cnt - lst[a[u]];
        ans[u] = sum + tmp;
        int pp = lst[a[u]];
        lst[a[u]] = cnt;
        sum += tmp;
        ++vis[a[u]];
        for(int i = head[u]; ~i; i = ed[i].next) {
            int v = ed[i].v;
            dfs(v);
        }
        sum -= tmp;
        --vis[a[u]];
        if(vis[a[u]] == 0) --cnt;
        lst[a[u]] = pp;
    }
     
    int main() {
        while(~scanf("%d", &n)) {
            tot = cnt = sum = 0;
            assert(n >= 1 && n <= 100000);
            for(int i = 1; i <= n; ++i) vis[i] = ans[i] = lst[i] = 0, head[i] = -1;
            for(int i = 2; i <= n; ++i) {
                scanf("%d", &u);
                assert(u >= 1 && u <= n && u != i);
                add(u, i);
            }
            for(int i = 1; i <= n; ++i) {
                scanf("%d", &a[i]);
                assert(a[i] >= 1 && a[i] <= n);
            }
            dfs(1);
            for(int i = 2; i <= n; ++i) printf("%d
    ", ans[i]);
        }
        return 0;
    }
    

    K题

    思路

    我们将(a)做个前缀和,然后考虑每个(b)的贡献即可。

    代码

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define fi first
    #define se second
    #define lson (rt<<1)
    #define rson (rt<<1|1)
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
    
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 500000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int n, m, L, R;
    LL sum[maxn], a[maxn], b[maxn];
     
    int main() {
        while (~scanf("%d%d%d%d", &n, &m, &L, &R)) {
            L += 2, R += 2;
            sum[0] = 0;
            for (int i = 1; i <= n + 1; i++) scanf("%lld", &a[i]), sum[i] = sum[i - 1] + a[i];
            for (int i = 1; i <= m + 1; i++) scanf("%lld", &b[i]);
            LL ans = 0;
            for (int i = 1; i <= m + 1; i++) {
                int l = max(1, L - i), r = min(n + 1, R - i);
                if (l > n + 1 || r < 1) continue;
                ans = (ans + 1LL * b[i] * ((sum[r] - sum[l - 1] + mod) % mod) % mod) % mod;
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    大牛思考方式
    web面试题大全
    github上最全的资源教程-前端涉及的所有知识体系
    java switch语句注意的事项
    Lucene Payload 的研究与应用
    hive array、map、struct使用
    黑马程序员--正则表达式
    [置顶] 读源码练内功(一):guava之eventbus
    自定义Java Annotations实例以及用Java Reflection来解析自定义的Annotation
    Solr之NamedList 简单介绍与实例解析
  • 原文地址:https://www.cnblogs.com/Dillonh/p/11621180.html
Copyright © 2020-2023  润新知