• 牛客练习赛85


    牛客练习赛85

    A - 科学家的模型

    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0), cout.tie(0);
     
        string s[5];
        for (int i = 0; i < 5; ++i)
            cin >> s[i];
     
        int x = -1, y, ans = 0;
        for (int i = 0; i < 5 && x == -1; ++i)
            for (int j = 0; j < 5 && x == -1; ++j)
                if (s[i][j] == '1') x = i, y = j;
     
        int len = 0;
        while (y + len < 5 && s[x][y + len] == '1')
            ++len;
     
        for (int i = x + 1; i < 5; ++i) {
            if (s[i][y + 1] == '1' && i < 4 && s[i + 1][y] == '1') ans = 8;
            if (s[i][y] ^ s[i][y + len - 1]) ans = 9;
            if (s[i][y] == '0' && s[i][y + len - 1] == '0') break;
        }
     
        cout << ans;
        return 0;
    }
    

    B - 科学家的模型

    尺取, 让你找三段,

    那就枚举中间的一段, 预处理左边的和右边的即可

    预处理用到尺取

    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0), cout.tie(0);
     
        int n, m, ans = 0;
        string s;
        cin >> n >> m >> s;
     
        vector<int> cnt(26), l(n), r(n);
     
        for (int i = 0, j = 0; i < n; ++i) {
            ++cnt[s[i] - 'a'];
     
            while (cnt[s[i] - 'a'] > m && j <= i)
                --cnt[s[j++] - 'a'];
     
            l[i] = i ? max(l[i - 1], i - j + 1) : i - j + 1;
        }
     
        cnt.assign(cnt.size(), 0);
        for (int i = n - 1, j = n - 1; ~i; --i) {
            ++cnt[s[i] - 'a'];
     
            while (cnt[s[i] - 'a'] > m && i >= i)
                --cnt[s[j--] - 'a'];
     
            r[i] = i != n - 1 ? max(r[i + 1], j - i + 1) : j - i + 1;
            ans = max(ans, (i ? l[i - 1] : 0) + j - i + 1 + (i != n - 1 ? r[j + 1] : 0));
        }
     
        cout << ans;
        return 0;
    }
    

    C - 哲学家的沉思

    典型的倍增题, 复杂度(O(nlogn))

    先倍增, 预处理

    (mx(i, j)) 表示区间 ([i, max(i + 2^j, n)]) 的最大值

    在通过(mx(i, j)) 预处理st表的(st(i, 0))

    (st(i, j)) 表示从位置(i)开始包含(2^j)个区间能到达最远的右端点(左闭右开)

    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0), cout.tie(0);
    
        int n, q, ans = 0;
        cin >> n >> q;
        
        vector<int> a(n);
        for (auto &i : a) cin >> i;
    
        vector<vector<int>> mx(n, vector<int>(17));
        for (int i = 0; i < n - 1; ++i)
            mx[i][0] = max(a[i], a[i + 1]);
        mx[n - 1][0] = 2e9;
    
        for (int j = 1; j < 17; ++j)
            for (int i = 0; i < n; ++i)
                mx[i][j] = max(mx[i][j - 1], mx[min(i + (1 << j - 1), n - 1)][j - 1]);
    
        vector<vector<int>> st(n + 1, vector<int>(17));
        for (int i = 0; i < n; ++i) {
            int r = i;
            for (int j = 16; ~j; --j)
                if (mx[r][j] <= a[i])
                    r += 1 << j;
            st[i][0] = r + 1;
        }
        st[n][0] = n;
        
        for (int j = 1; j < 17; ++j)
            for (int i = 0; i <= n; ++i)
                st[i][j] = st[st[i][j - 1]][j - 1];
    
        while (q--) {
            int l, r, ans = 1;
            cin >> l >> r;
            --l, --r;
    
            for (int i = 16; i >= 0; --i)
                if (st[l][i] <= r)
                    ans += 1 << i, l = st[l][i];
    
            cout << ans << '
    ';
        }
        return 0;
    }
    

    用bitset维护所含的质数

    线段树维护区间bitset即可

    const int N = 1e5 + 5, M = 9592;
    
    struct BIT {
        static const int N = 5e4 + 5;
        bitset<M> tr[N << 2];
    
        void push_up(int p) {
            tr[p] = tr[p << 1] | tr[p << 1 | 1];
        }
    
        void change(int p, int l, int r, int k, bitset<M> &v) {
            if (l == k && r == k) {
                tr[p] = v;
                return;
            }
            int mid = l + r >> 1;
            if (mid >= k) change(p << 1, l, mid, k, v);
            else change(p << 1 | 1, mid + 1, r, k, v);
            push_up(p);
        }
    
        bitset<M> ask(int p, int l, int r, int L, int R) {
            if (L <= l && r <= R) return tr[p];
            int mid = l + r >> 1;
            if (mid >= R) return ask(p << 1, l, mid, L, R);
            if (mid < L) return ask(p << 1 | 1, mid + 1, r, L ,R);
            return ask(p << 1, l, mid, L, R) | ask(p << 1 | 1, mid + 1, r, L, R);
        }
    } bit;
    
    int pri[M], tot;
    bool v[N];
    bitset<M> ve;
    
    void init(int n) {
        for (int i = 2; i <= n; ++i) {
            if (!v[i]) pri[tot++] = i;
            for (int j = 0; j < tot && pri[j] <= n / i; ++j) {
                v[pri[j] * i] = 1;
                if (i % pri[j] == 0) break;
            }
        }
    }
    
    void setbit(int n) {
        ve = 0;
        for (int i = 0; pri[i] <= n / pri[i]; ++i)
            if (n % pri[i] == 0) {
                ve[i] = 1;
                while (n % pri[i] == 0) n /= pri[i];
            }
        if (n - 1)
            ve[lower_bound(pri, pri + tot, n) - pri] = 1;
    }
    
    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0), cout.tie(0);
    
        init(1e5);
        int n, m;
        cin >> n >> m;
        for (int i = 1; i <= n; ++i) {
            int x;
            cin >> x;
            setbit(x);
            bit.change(1, 1, n, i, ve);
        }
    
        while (m--) {
            int op, x, y;
            cin >> op >> x >> y;
    
            if (op == 1) {
                setbit(y);
                bit.change(1, 1, n, x, ve);
            }
            else
                cout << bit.ask(1, 1, n, x, y).count() << '
    ';
        }
        return 0;
    }
    
  • 相关阅读:
    张五常:思考的方法
    David Foster Wallace on Life and Work
    SQL SERVER SQL Agent服务使用小结
    js大全
    中国载人航天工程七大系统
    vc 编译遇到问题
    学习Excel技巧
    使用Request.ServerVariables获取环境变量
    c# 字符常用函数
    SQL数据同步
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/14979459.html
Copyright © 2020-2023  润新知