• Codeforces Round #353(Div 2)


    信息课闲着无聊打的一场cf模拟赛。

    A题:

    *题目描述:
    已知一个等差数列的首项和公差,问某个数在不在等差数列内?
    *题解:
    直接模拟,注意零和负数要判,不然直接模会出错。
    *代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    
    #ifdef WIN32
        #define LL "%I64d"
    #else
        #define LL "%lld"
    #endif
    
    #ifdef CT
        #define debug(...) printf(__VA_ARGS__)
        #define setfile() 
    #else
        #define debug(...)
        #define filename ""
        #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
    #endif
    
    #define R register
    #define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
    #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
    #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
    #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
    #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
    char B[1 << 15], *S = B, *T = B;
    inline int FastIn()
    {
        R char ch; R int cnt = 0; R bool minus = 0;
        while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
        ch == '-' ? minus = 1 : cnt = ch - '0';
        while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
        return minus ? -cnt : cnt;
    }
    
    int main()
    {
    //  setfile();
        R int a = FastIn(), b = FastIn(), c = FastIn();
        bool ans;
        if (!c) ans = a == b;
        else
            if (c > 0) ans = b >= a && ((b - a) % c == 0);
            else ans = b <= a && ((a - b) % (-c) == 0);
        printf(ans ? "YES" : "NO");
        return 0;
    }

    B题:

    *题目描述:
    已知一个3*3矩阵的(1,2)(2,1)(2,3)(3,2)四个点,求剩下的五个空有多少种不同的方案,使得每个2*2方格内的数之和都相等,同时保证填上去的数都在1~n范围内。
    *题解:
    设左上角的数为x,根据等量关系可以推出剩下三个角上面的表达式,然后就枚举x,判断剩下三个数是不是合法的就可以,中间那个数填什么都可以,所以答案*n就可以了。
    *代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    
    #ifdef WIN32
        #define LL "%I64d"
    #else
        #define LL "%lld"
    #endif
    
    #ifdef CT
        #define debug(...) printf(__VA_ARGS__)
        #define setfile() 
    #else
        #define debug(...)
        #define filename ""
        #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
    #endif
    
    #define R register
    #define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
    #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
    #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
    #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
    #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
    char B[1 << 15], *S = B, *T = B;
    inline int FastIn()
    {
        R char ch; R int cnt = 0; R bool minus = 0;
        while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
        ch == '-' ? minus = 1 : cnt = ch - '0';
        while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
        return minus ? -cnt : cnt;
    }
    
    int main()
    {
    //  setfile();
        R int n = FastIn(), a = FastIn(), b = FastIn(), c = FastIn(), d = FastIn();
        R long long ans = 0;
        #define ok(_x) ((_x) >= 1 && (_x) <= n)
        for (R int i = 1; i <= n; ++i)
            if (ok(i + b - c) && ok(i + a - d) && ok(i + a + b - c - d)) ++ans;
        printf(LL"
    ", ans * n);
        return 0;
    }

    C题:

    *题目描述:
    有一个长度为n的数组a,每一次可以将某个位置的数移到旁边的位置上(1的旁边是2和n,n的旁边是n-1和1),问最少的移动步数是多少?
    *题解:
    答案就是n-前缀和出现次数的最多的次数。因为这是一个环,每次出现一个和为0的段,那么此处的答案就是这段的长度-1,所以只要统计有多少个答案为0的段。所以我们把所有的前缀和都取出来,两个相同的前缀和之间一定是和为0的段,所以n-出现次数最多的前缀和就是答案。
    *代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    
    #ifdef WIN32
        #define LL "%I64d"
    #else
        #define LL "%lld"
    #endif
    
    #ifdef CT
        #define debug(...) printf(__VA_ARGS__)
        #define setfile() 
    #else
        #define debug(...)
        #define filename ""
        #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
    #endif
    
    #define R register
    #define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
    #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
    #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
    #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
    #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
    char B[1 << 15], *S = B, *T = B;
    inline int FastIn()
    {
        R char ch; R int cnt = 0; R bool minus = 0;
        while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
        ch == '-' ? minus = 1 : cnt = ch - '0';
        while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
        return minus ? -cnt : cnt;
    }
    #include <map>
    std::map<long long, int> cnt;
    int main()
    {
    //  setfile();
        R int n = FastIn(), ans = 1;
        R long long s = 0;
        for (R int i = 1; i <= n; ++i)
        {
            s += FastIn();
            ++cnt[s];
            cmax(ans, cnt[s]);
        }
        printf("%d
    ", n - ans );
        return 0;
    }

    D题:

    *题目描述:
    给定一棵BST的插入的顺序,输出每次插入的节点的父亲。
    *题解:
    比赛的时候sb地写了一个模拟每次在BST上暴力插,结果交上去光荣地T了,突然想到一条链的话就被卡成n2的了。然后自己画了画图,发现答案就是序列里的upper_bound。我当时对此的解决方法是离散化后用链表把所有的数串起来,然后倒序处理插入操作,这样就变成了在树上的删除操作,可以用链表来维护,这样它的父亲就是链表左右两端的出现时间的较大值。(我也不知道当时是怎么想出这个算法的,也不知道是不是对的,但是不知道为什么交上去运气好居然就ac了)
    *代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    
    #ifdef WIN32
        #define LL "%I64d"
    #else
        #define LL "%lld"
    #endif
    
    #ifdef CT
        #define debug(...) printf(__VA_ARGS__)
        #define setfile() 
    #else
        #define debug(...)
        #define filename ""
        #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
    #endif
    
    #define R register
    #define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
    #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
    #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
    #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
    #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
    char B[1 << 15], *S = B, *T = B;
    inline int FastIn()
    {
        R char ch; R int cnt = 0; R bool minus = 0;
        while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
        ch == '-' ? minus = 1 : cnt = ch - '0';
        while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
        return minus ? -cnt : cnt;
    }
    #define maxn 100010
    int a[maxn], b[maxn], next[maxn], prev[maxn], n, tim[maxn], ans[maxn];
    int main()
    {
    //  setfile();
        n = FastIn();
        for (R int i = 1; i <= n; ++i)
            a[i] = b[i] = FastIn();
        std::sort(b + 1, b + n + 1);
        for (R int i = 1; i <= n; ++i)
            a[i] = std::lower_bound(b + 1, b + n + 1, a[i]) - b, 
            tim[a[i]] = i, next[i] = i + 1, prev[i] = i - 1;
        tim[0] = tim[n + 1] = 0;
        for (R int i = n; i > 1; --i)
        {
            next[prev[a[i]]] = next[a[i]];
            prev[next[a[i]]] = prev[a[i]];
            ans[i] = b[tim[next[a[i]]] > tim[prev[a[i]]] ? next[a[i]] : prev[a[i]]];
        }
        for (R int i = 2; i <= n; ++i) printf("%d ", ans[i] );
        return 0;
    }

    E题:

    *题目描述:
    有n个站点,对于站点i(1i<n) ,它到达i+1ai的代价都为1,且不能往编号小于它的点走。求最短路的邻接矩阵的总和。
    *题解:
    第一眼是floyd,发现数据范围跑不过。(于是考场就弃疗了),于是就想DP,对于每个i,枚举自己所能到达的点的ai 最大的点。写出DP方程:dpi=dpj(aij)+ni1,其中j为上述的最优的点。然后j可以用线段树/树状数组/ST表来维护,于是复杂度降为O(nlogn)
    *代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    
    #ifdef WIN32
        #define LL "%I64d"
    #else
        #define LL "%lld"
    #endif
    
    #ifdef CT
        #define debug(...) printf(__VA_ARGS__)
        #define setfile() 
    #else
        #define debug(...)
        #define filename ""
        #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
    #endif
    
    #define R register
    #define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
    #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
    #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
    #define cmax(_a, _b) (_a < (_b) ? _a = (_b), 0 : 0)
    #define cmin(_a, _b) (_a > (_b) ? _a = (_b), 0 : 0)
    char B[1 << 15], *S = B, *T = B;
    inline int FastIn()
    {
        R char ch; R int cnt = 0; R bool minus = 0;
        while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
        ch == '-' ? minus = 1 : cnt = ch - '0';
        while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
        return minus ? -cnt : cnt;
    }
    #define maxn 1 << 20
    int a[maxn], M, n;
    struct Seg
    {
        int val, pos;
        inline bool operator < (const Seg &that) const {return val < that.val || (val == that.val && pos < that.pos); }
        inline bool operator > (const Seg &that) const {return val > that.val || (val == that.val && pos > that.pos); }
    }tr[maxn];
    inline void Build()
    {
        for (R int i = 0; i < n; ++i) tr[i + M] = (Seg){a[i], i};
        for (R int i = M - 1; i; --i)
            tr[i] = dmax(tr[i << 1], tr[i << 1 | 1]);
    }
    inline int get(R int s, R int t)
    {
        Seg ans = (Seg) {-1, -1};
        for (s = s + M - 1, t = t + M + 1; s ^ t ^ 1; s >>= 1, t >>= 1)
        {
            if (~ s & 1) cmax(ans, tr[s ^ 1]);
            if (t & 1) cmax(ans, tr[t ^ 1]);
        }
        return ans.pos;
    }
    long long dp[maxn];
    int main()
    {
    //  setfile();
        n = FastIn();
        for (R int i = 0; i < n - 1; ++i)
            a[i] = FastIn() - 1;
        a[n - 1] = n - 1;
        for (M = 1; M < n; M <<= 1);
        Build();
        R long long ans = 0;
        for (R int i = n - 2; i >= 0; --i)
        {
            R int m = get(i + 1, a[i]);
            dp[i] = dp[m] - (a[i] - m) + n - i - 1;
            ans += dp[i];
        }
        printf(LL"
    ", ans);
        return 0;
    }
  • 相关阅读:
    一个在线的C++帮助文档网站
    linux 学习笔记 (四)
    类的static成员函数和const成员函数
    Linux的inode、软链接、硬链接
    常用linux命令(三)
    多语言调用之 C++ 调用 Java JNI
    多语言调用之 Java调用C/C++
    NHibernate 操作原生SQL以及查询DataTable,DataSet
    DataGridView控件用法合集
    Java AOP实战 寻找SQL的引用路径
  • 原文地址:https://www.cnblogs.com/cocottt/p/6765004.html
Copyright © 2020-2023  润新知