zoukankan      html  css  js  c++  java
  • Codeforces Round #448

    Pizza Serparation

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    #include<map>
    #include<queue>
    using std::vector;
    using std::queue;
    using std::map;
    using std::sort;
    using std::string;
    #define read(x) scanf("%d",&x)
    #define reads(x) scanf("%s",x)
    
    int cmp(const void * x, const void * y) {
    #define datatype int
        datatype dx = *((datatype *)(x)), dy = *((datatype *)(y));
        //x < y
        return dx > dy ? 1 : -1;
    #undef datatype
    }
    
    int a[400], nex[400];
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
    #endif
        int n;
        read(n);
        for (int i = 0; i < n; i++) {
            read(a[i]);
            nex[i] = i + 1;
        }
        nex[n - 1] = 0;
        int ans = 0x3FFFFFFF;
        for (int i = 0; i < n; i++) {
            int sum = 0;
            for (int j = i;; j = nex[j]) {
                sum += a[j];
                if (sum >= 180) break;
            }
            if (2 * (sum - 180) < ans) ans = 2 * (sum - 180);
        }
        printf("%d
    ", ans);
        return 0;
    }
    View Code

    XK Segments

    STL真是手残拯救者

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<string>
    using std::vector;
    using std::queue;
    using std::map;
    using std::sort;
    using std::string;
    using std::lower_bound;
    using std::upper_bound;
    #define read(x) scanf("%d", &x)
    #define reads(x) scanf("%s", x)
    #define write(x) printf("%d ", x)
    #define writes(x) printf("%s ", x)
    #define writeln(x) printf("%d
    ", x)
    #define writesln(x) printf("%s
    ", x)
    typedef long long llint;
    /*data structure*/
    
    /*data structure*/
    int cmp(const void * x, const void * y) {
    #define datatype int
        datatype dx = *((datatype *)(x)), dy = *((datatype *)(y));
        //x < y
        return dx > dy ? 1 : -1;
    #undef datatype
    }
    /*global variable*/
    map<llint, int> mp;
    vector<llint> v;
    int sum[100005];
    /*global variable*/
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
    #endif
        int n;
        llint a, ap, h, l, b, x, k;
        while (scanf("%d%lld%lld", &n, &x, &k) != EOF) {
            mp.clear();
            v.clear();
            for (int i = 0; i < n; i++) {
                scanf("%lld", &a);
                if (mp.find(a) == mp.end()) v.push_back(a);
                mp[a]++;
            }
            sort(v.begin(), v.end());
            sum[0] = mp[v[0]];
            for (int i = 1; i < v.size(); i++) sum[i] = sum[i - 1] + mp[v[i]];
            llint ans = 0;
            for (int i = 0; i < v.size(); i++) {
                a = v[i];
                if (a % x == 0) ap = a;
                else ap = a - a % x + x;
                if (k == 0) {
                    h = ap - 1;
                    l = a;
                } else {
                    ap += x * (k - 1);
                    l = ap;
                    h = ap + x - 1;
                }
                if (l > h) continue;
                int s = lower_bound(v.begin(), v.end(), l) - v.begin(), e = lower_bound(v.begin(), v.end(), h) - v.begin();
                if (e == v.end() - v.begin()) e--;
                if (v[e] > h) e--;
                if (s == v.end() - v.begin()) continue;
                ans += (llint)mp[a] * (llint)(sum[e] - sum[s] + mp[v[s]]);
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    View Code

    Square Subsets

    首先,其中本来就是完全平方数的数,爱取多少取多少,不影响结果,只需最终结果乘以2^a[i]

    对于不是完全平方数的数,只需关心其取了奇数个还是偶数个,具体数目不影响结果,因此可以看成只取0个或1个,最终结果乘以2^(a[i]-1)。

    将1-70的数分解质因数,记录每个数的各个因子有奇数个还是偶数个。

    1-70间的质数共19个,用0-2^19-1表示所有状态,第i为为1表示第i个质数有奇数个,为0表示有偶数个。

    dp[i]表示达到i这种质因子奇偶状态的方法数,dp[0]表示完全平方数的方法数。

    最终结果减1,去掉空集。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<string>
    using std::vector;
    using std::queue;
    using std::map;
    using std::sort;
    using std::string;
    using std::lower_bound;
    using std::upper_bound;
    #define read(x) scanf("%d", &x)
    #define reads(x) scanf("%s", x)
    #define write(x) printf("%d ", x)
    #define writes(x) printf("%s ", x)
    #define writeln(x) printf("%d
    ", x)
    #define writesln(x) printf("%s
    ", x)
    #define fillchar(x, a) memset(x, a, sizeof(x))
    typedef long long llint;
    /*data structure*/
    
    /*data structure*/
    int cmp(const void * x, const void * y) {
    #define datatype int
        datatype dx = *((datatype *)(x)), dy = *((datatype *)(y));
        //x < y
        return dx > dy ? 1 : -1;
    #undef datatype
    }
    /*global variable*/
    const int p[19] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67};
    const llint mod = 1000000007;
    int a[80], v[80][19];
    llint dp[2][1 << 19];
    /*global variable*/
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
    #endif
        int n, x;
        read(n);
        fillchar(a, 0);
        fillchar(v, 0);
        for (int i = 0; i < n; i++) {
            read(x);
            a[x]++;
        }
        int multp = 0;
        for (int i = 1; i <= 8; i++) {
            multp += a[i * i];
            a[i * i] = 0;
        }
        for (int i = 1; i <= 70; i++) {
            if (a[i]) multp += (a[i] - 1);
        }
        for (int i = 1; i <= 70; i++) {
            x = i;
            for (int j = 0; j < 19; j++) {
                while (x % p[j] == 0) {
                    v[i][j] = 1 - v[i][j];
                    x /= p[j];
                }
            }
        }
        fillchar(dp, 0);
        dp[0][0] = 1;
        int last = 0, cur;
        for (int i = 1; i <= 70; i++) {
            if (a[i] == 0) continue;
            cur = 1 - last;
            for (int j = 0; j < (1 << 19); j++) dp[cur][j] = 0;
            for (int j = 0; j < (1 << 19); j++) {
                int state = j;
                if (dp[last][state] == 0) continue;
                for (int k = 0; k < 19; k++) {
                    state ^= (v[i][k] << k);
                }
                dp[cur][state] = (dp[cur][state] + dp[last][j]) % mod;
            }
            for (int j = 0; j < (1 << 19); j++) {
                dp[cur][j] = (dp[cur][j] + dp[last][j]) % mod;
            }
            last = cur;
        }
        llint ans = dp[last][0];
        for (int i = 0; i < multp; i++) {
            ans = ans * 2 % mod;
        }
        printf("%lld
    ", ans - 1);
        return 0;
    }
    View Code

    String Mark

    设f(s)为用字符串a组合能产生比s小的字符串的个数,答案为f(b)-f(a)-1,一位一位算就可以了。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<string>
    #include<functional>
    #include<iostream>
    using std::priority_queue;
    using std::vector;
    using std::queue;
    using std::map;
    using std::sort;
    using std::string;
    using std::lower_bound;
    using std::upper_bound;
    using std::cin;
    using std::cout;
    using std::endl;
    #define fillchar(x, a) memset(x, a, sizeof(x))
    typedef long long lint;
    /*data structure*/
    
    /*data structure*/
    int cmp(const void * x, const void * y) {
    #define datatype int
        datatype dx = *((datatype *)(x)), dy = *((datatype *)(y));
        //x < y
        return dx > dy ? 1 : -1;
    #undef datatype
    }
    /*global variable*/
    char a[1000005], b[1000005];
    lint fac[1000005], ifac[1000005];
    int cnt[26], n;
    const lint mod = 1000000007;
    /*global variable*/
    /*function*/
    inline lint pow(lint a, lint b, lint p) {
        lint rtn = 1;
        while (b) {
            if (b & 1) rtn = rtn * a % p;
            a = a * a % p;
            b >>= 1;
        }
        return rtn;
    }
    lint f(char * s) {
        fillchar(cnt, 0);
        for (int i = 0; i < n; i++) cnt[a[i] - 'a']++;
        lint div = 1;
        for (int i = 0; i < 26; i++) div = div * ifac[cnt[i]] % mod;
        lint rtn = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < s[i] - 'a'; j++) {
                if (cnt[j]) {
                    rtn = (rtn + fac[n - i - 1] * cnt[j] % mod * div % mod) % mod;
                }
            }
            if (cnt[s[i] - 'a'] == 0) return rtn;
            div = div * cnt[s[i] - 'a'] % mod;
            cnt[s[i] - 'a']--;
        }
        return rtn;
    }
    /*function*/
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
    #endif
        std::ios::sync_with_stdio(0), cin.tie(0);
        cin >> a >> b;
        n = strlen(a);
        fac[0] = ifac[0] = 1;
        for (int i = 1; i <= n; i++) {
            fac[i] = fac[i - 1] * i % mod;
            ifac[i] = pow(fac[i], mod - 2, mod);
        }
        cout << (f(b) - f(a) - 1 + mod) % mod << endl;
        return 0;
    }
    View Code

    Eyes Closed

    每个线段里随机选个数,选出来的数期望为线段里的数的平均数,设为a。对于长度为l的线段里的一个数字x,其保持不变的概率为(l-1)/l,被选出来交换的概率为1/l,则其期望为ex=x*(l-1)/l+a/l,即操作后线段里每个数字的期望为原数字乘以一个常数再加一个常数,可以用线段树来实现这个操作,把lazy标记分成两部分即可。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<string>
    using std::vector;
    using std::queue;
    using std::map;
    using std::sort;
    using std::string;
    using std::lower_bound;
    using std::upper_bound;
    #define read(x) scanf("%d", &x)
    #define reads(x) scanf("%s", x)
    #define write(x) printf("%d ", x)
    #define writes(x) printf("%s ", x)
    #define writeln(x) printf("%d
    ", x)
    #define writesln(x) printf("%s
    ", x)
    #define fillchar(x, a) memset(x, a, sizeof(x))
    typedef long long llint;
    /*data structure*/
    template <class T> class SegmentTree {
    public:
        T dat, lazym, lazyp;
        int leftBorder, rightBorder, mid;
        SegmentTree * leftSon, * rightSon;
        SegmentTree() {
            leftBorder = rightBorder = -1;
            leftSon = rightSon = NULL;
        }
        void pushdown();
        void pushup();
        void Build(T *, int, int);
        void Modify(int, int, T, T);
        T Query(int, int);
        void Free();
    };
    template<class T> void SegmentTree<T>::pushdown() {
        if ((lazym != 1 || lazyp != (T)0) && leftBorder != rightBorder) {
            leftSon->dat = leftSon->dat * lazym + lazyp * (leftSon->rightBorder - leftSon->leftBorder + 1);
            rightSon->dat = rightSon->dat * lazym + lazyp * (rightSon->rightBorder - rightSon->leftBorder + 1);
            leftSon->lazym *= lazym;
            leftSon->lazyp = leftSon->lazyp * lazym + lazyp;
            rightSon->lazym *= lazym;
            rightSon->lazyp = rightSon->lazyp * lazym + lazyp;
        }
        lazym = (T)1;
        lazyp = (T)0;
    }
    template<class T> void SegmentTree<T>::pushup() {
        dat = leftSon->dat + rightSon->dat;
    }
    template<class T> void SegmentTree<T>::Build(T * S, int l, int r) {
        if (l > r) {
            return;
        }
        lazym = (T)1;
        lazyp = (T)0;
        leftBorder = l;
        rightBorder = r;
        mid = (leftBorder + rightBorder) >> 1;
        if (l == r) {
            dat = S[l];
            return;
        }
        leftSon = new SegmentTree;
        leftSon->Build(S, l, mid);
        rightSon = new SegmentTree;
        rightSon->Build(S, mid + 1, r);
        pushup();
    }
    template<class T> void SegmentTree<T>::Modify(int l, int r, T mult, T plus) {
        if (l > r || l < leftBorder || rightBorder < r) {
            return;
        }
        if (leftBorder == l && rightBorder == r) {
            dat = dat * mult + plus * (rightBorder - leftBorder + 1);
            lazym *= mult;
            lazyp = lazyp * mult + plus;
            return;
        }
        pushdown();
        if (r <= mid) {
            leftSon->Modify(l, r, mult, plus);
        } else if (mid < l) {
            rightSon->Modify(l, r, mult, plus);
        } else {
            leftSon->Modify(l, mid, mult, plus);
            rightSon->Modify(mid + 1, r, mult, plus);
        }
        pushup();
    }
    template<class T> T SegmentTree<T>::Query(int l, int r) {
        if (l > r || l < leftBorder || rightBorder < r) {
            return dat;
        }
        pushdown();
        if (l == leftBorder && r == rightBorder) {
            return dat;
        }
        if (r <= mid) {
            return leftSon->Query(l, r);
        } else if (mid < l) {
            return rightSon->Query(l, r);
        } else {
            return leftSon->Query(l, mid) + rightSon->Query(mid + 1, r);
        }
    }
    template<class T> void SegmentTree<T>::Free() {
        if (leftSon != NULL) {
            leftSon->Free();
        }
        if (rightSon != NULL) {
            rightSon->Free();
        }
        delete leftSon;
        delete rightSon;
    }
    /*data structure*/
    int cmp(const void * x, const void * y) {
    #define datatype int
        datatype dx = *((datatype *)(x)), dy = *((datatype *)(y));
        //x < y
        return dx > dy ? 1 : -1;
    #undef datatype
    }
    /*global variable*/
    SegmentTree<double> st;
    double a[100005];
    /*global variable*/
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
    #endif
        int n, q;
        read(n);
        read(q);
        for (int i = 0; i < n; i++) scanf("%lf", &a[i]);
        st.Build(a, 0, n - 1);
        int t, l1, l2, l, r1, r2, r;
        for (int i = 0; i < q; i++) {
            read(t);
            if (t == 1) {
                read(l1);
                read(r1);
                read(l2);
                read(r2);
                l1--, r1--, l2--, r2--;
                double sum1 = st.Query(l1, r1), sum2 = st.Query(l2, r2);
                double ave1 = sum1 / (r1 - l1 + 1.0), ave2 = sum2 / (r2 - l2 + 1.0);
                st.Modify(l1, r1, (r1 - l1) / (r1 - l1 + 1.0), ave2 / (r1 - l1 + 1.0));
                st.Modify(l2, r2, (r2 - l2) / (r2 - l2 + 1.0), ave1 / (r2 - l2 + 1.0));
            } else {
                read(l);
                read(r);
                l--, r--;
                double ans = st.Query(l, r);
                printf("%.7lf
    ", ans);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    我爱淘冲刺阶段站立会议每天任务2
    我爱淘冲刺阶段站立会议每天任务1
    大道至简-灵活的软件工程
    大道至简-实现,才是目的
    冲刺第二阶段工作总结06
    课堂练习-最低价购书方案
    构建之法阅读笔记04
    冲刺第二阶段工作总结05
    冲刺第二阶段工作总结04
    冲刺第二阶段工作总结03
  • 原文地址:https://www.cnblogs.com/dramstadt/p/7902610.html
Copyright © 2011-2022 走看看