zoukankan      html  css  js  c++  java
  • 818E

    818E - Card Game Again

    题意

    给出一个数列,选择连续的一段使得这些数字的乘积是 k 的倍数,问合法的方案数。

    分析

    尺取法。设 num 为连续的数的乘积,只要对于 k 的每个素因子,num 相应的素因子的个数大于等于它。那么不仅这个数,后面乘上任意数都是 k 的倍数。这时候就不用移动 r 指针了,移动 l 指针,即不断的去掉前面的数。
    计算时可以用 map 存下素因子及其个数。

    code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 1e5 + 5;
    const int MAXN = 3e4 + 2e3;
    const int INF = 2e9 + 1;
    int is[MAXN];
    vector<int> prime;
    void init() {
        for(int i = 2; i < MAXN; i++) {
            if(!is[i]) {
                prime.push_back(i);
                for(ll j = 1LL * i * i; j < MAXN; j += i) {
                    is[j] = 1;
                }
            }
        }
    }
    int a[N];
    struct nd {
        int x, cnt;
    };
    vector<nd> getFactor(int x) {
        vector<nd> v;
        for(int i = 0; 1LL * prime[i] * prime[i] <= x; i++) {
            int c = 0;
            while(x % prime[i] == 0) {
                x /= prime[i];
                c++;
            }
            if(c) v.push_back(nd{prime[i], c});
        }
        if(x > 1) v.push_back(nd{x, 1});
        return v;
    }
    map<int, vector<nd> > mp;
    int C[MAXN];
    set<int> st;
    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        init();
        int n, k;
        cin >> n >> k;
        for(int i = 0; i < n; i++) {
            cin >> a[i];
        }
        int l = 0, r = 0;
        vector<nd> K = getFactor(k);
        ll ans = 0;
        int state = 1;
        while(l < n && r < n) {
            vector<nd> X;
            if(state) {
                if(!mp.count(a[r])) mp[a[r]] = getFactor(a[r]);
                X = mp[a[r]];
                for(int i = 0; i < X.size(); i++) {
                    if(X[i].x > MAXN) st.insert(X[i].x);
                    else C[X[i].x] += X[i].cnt;
                }
            } else {
                if(!mp.count(a[l])) mp[a[l]] = getFactor(a[l]);
                X = mp[a[l]];
                for(int i = 0; i < X.size(); i++) {
                    if(X[i].x > MAXN) st.erase(X[i].x);
                    else C[X[i].x] -= X[i].cnt;
                }
                l++;
            }
            int flg = 0;
            for(int i = 0; i < K.size(); i++) {
                if(K[i].x > MAXN) { if(!st.count(K[i].x)) { flg = 1; break; } }
                else if(K[i].cnt > C[K[i].x]) { flg = 1; break; }
            }
            if(flg) {
                r++;
                state = 1;
            } else {
                ans += n - r;
                if(l == r) { r++; l++; state = 1; memset(C, 0, sizeof C); st.clear(); }
                else state = 0;
            }
        }
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    web自动化搞定文件上传
    App自动化08-Android SDK目录架构详解
    App自动化07-Appium日志分析,深入剖析 Appium 实现原理
    App自动化06-adb常见连接问题整理
    crontab 定时任务
    谷歌对华为断供了,那自动化测试还做吗?
    Fiddler 抓取 https 请求大全
    App自动化05-adb
    App自动化04-Inspector检查器启动QQ测试
    (转载)边缘计算与深度学习综述
  • 原文地址:https://www.cnblogs.com/ftae/p/7151480.html
Copyright © 2011-2022 走看看