[Codeforces]Codeforces Round #489 (Div. 2)

Nastya and an Array

输出有几种不同的数字

#pragma comment(linker, "/STACK:102400000,102400000")
#ifndef ONLINE_JUDGE
#include "stdafx.h"
#else
#include<bits/stdc++.h>
#endif
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef queue<int> QI;
typedef map<int, int> MII;

void makedata() {
    freopen("input.txt", "w", stdout);
    fclose(stdout);
}

int p[150000], q[150000];

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    //makedata();
    std::ios::sync_with_stdio(0), cin.tie(0);
    int n, x;
    cin >> n;
    int ans = 0;
    for (int i = 0; i < n; i++) {
        cin >> x;
        if (x > 0) {
            if (!p[x]) ans++;
            p[x] = true;
        }
        if (x < 0) {
            if (!q[-x]) ans++;
            q[-x] = true;
        }
    }
    cout << ans << endl;
    return 0;
}
View Code

Nastya Studies Informatics

把y/x分解质因数,a和b各自占有一部分且不重复

#pragma comment(linker, "/STACK:102400000,102400000")
#ifndef ONLINE_JUDGE
#include "stdafx.h"
#else
#include<bits/stdc++.h>
#endif
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef queue<int> QI;
typedef map<int, int> MII;

void makedata() {
    freopen("input.txt", "w", stdout);
    fclose(stdout);
}

bool f[1000000];
int p[100];

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    //makedata();
    std::ios::sync_with_stdio(0), cin.tie(0);
    memset(f, true, sizeof(f));
    f[0] = f[1] = false;
    for (int i = 2; i < 1000000; i++) {
        for (int j = i + i; j < 1000000; j += i) f[j] = false;
    }
    int l, r, x, y;
    cin >> l >> r >> x >> y;
    if (y % x != 0) {
        cout << 0 << endl;
        return 0;
    }
    int m = y / x, sz = 0;
    for (int i = 2; i < 1000000; i++) {
        if (m == 1) break;
        if (!f[i]) continue;
        if (m % i == 0) {
            int tmp = 1;
            while (m % i == 0) {
                m /= i;
                tmp *= i;
            }
            p[sz++] = tmp;
        }
    }
    if (m != 1) p[sz++] = m;
    m = y / x;
    int ans = 0;
    for (int i = 0; i < (1 << sz); i++) {
        int a = 1, b;
        for (int j = 0; j < sz; j++) {
            if (i & (1 << j)) a *= p[j];
        }
        b = m / a;
        if (l <= a * x && a * x <= r && l <= b * x && b * x <= r) ans++;
    }
    cout << ans << endl;
    return 0;
}
View Code

Nastya and a Wardrobe

每次x2-0.5

#pragma comment(linker, "/STACK:102400000,102400000")
#ifndef ONLINE_JUDGE
#include "stdafx.h"
#else
#include<bits/stdc++.h>
#endif
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef queue<int> QI;
typedef map<int, int> MII;

void makedata() {
    freopen("input.txt", "w", stdout);
    fclose(stdout);
}

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;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    //makedata();
    std::ios::sync_with_stdio(0), cin.tie(0);
    lint x, k;
    cin >> x >> k;
    lint p = 1000000007;
    if (k == 0) {
        cout << (x * 2 % p) << endl;
        return 0;
    }
    if (x == 0) {
        cout << 0 << endl;
        return 0;
    }
    lint a = pow(2, k, p) * (x % p) % p, b = pow(2, k - 1, p);
    //a-b+0.5->2a-2b+1
    cout << ((2 * a - 2 * b + 1) % p + p) % p << endl;
    return 0;
}
/*
2(2x - 0.5) - 0.5
2x - 0.5 1
4x - 1.5 2
8x - 3.5 4
16x - 7.5 8
32x - 15.5 16
*/
View Code

Nastya and a Game

枚举左端点然后依次往右找,对于一段连续的1可以根据范围直接判断。因为S的最大值不超过2*10^18,所以向右找的次数不超过120次。

#pragma comment(linker, "/STACK:102400000,102400000")
#ifndef ONLINE_JUDGE
#include "stdafx.h"
#else
#include<bits/stdc++.h>
#endif
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef queue<int> QI;
typedef map<int, int> MII;

void makedata() {
    freopen("input.txt", "w", stdout);
    fclose(stdout);
}

lint a[250000], s[250000];
int r[250000];
double ln[250000];
double inf = log(1LL << 60);

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    //makedata();
    std::ios::sync_with_stdio(0), cin.tie(0);
    int n, k;
    cin >> n >> k;
    s[0] = 0;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        s[i] = s[i - 1] + a[i];
        ln[i] = log(a[i]);
    }
    for (int i = n; i >= 1; i--) {
        if (a[i] == 1) {
            if (a[i + 1] == 1) r[i] = r[i + 1];
            else r[i] = i;
        }
    }
    lint ans = 0;
    if (k == 1) ans = n;
    for (int i = 1; i <= n; i++) {
        int j = i + 1;
        lint m = a[i];
        double p = ln[i];
        while (j <= n) {
            if (a[j] == 1) {
                if (m % k == 0) {
                    lint tmp = m / k;
                    if (s[j] - s[i - 1] <= tmp && tmp <= s[r[j]] - s[i - 1]) ans++;
                }
                j = r[j] + 1;
            } else {
                if (p + ln[j] >= inf) break;
                p += ln[j];
                m *= a[j];
                if (m == (s[j] - s[i - 1])*k) ans++;
                j++;
            }
        }
    }
    cout << ans << endl;
    return 0;
}
View Code

Nastya and King-Shamans

两个线段树,一个维护sum,一个维护max。对每个询问,如果a[1]=0直接输出1,否则令m=1,显然此时[1,m]里没有萨满王。对于m之后的,想成为萨满王其能力值至少为sum(1,m),找到第一个满足条件的萨满p,判断p是不是萨满王,如果不是则令m=p,直到找到或确定没有。

#pragma comment(linker, "/STACK:102400000,102400000")
#ifndef ONLINE_JUDGE
#include "stdafx.h"
#else
#include<bits/stdc++.h>
#endif
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef queue<int> QI;
typedef map<int, int> MII;

void makedata() {
    freopen("input.txt", "w", stdout);
    fclose(stdout);
}

lint a[250000];
int n, q;
template <typename T> class SegmentTree {
    /*
    type:
    0:sum
    1:max
    */
private:
    T *data, *lazy;
    int type;
    void pushup(int rt) {
        if (type == 0)
            data[rt] = data[rt << 1] + data[rt << 1 | 1];
        else if (type == 1)
            data[rt] = max(data[rt << 1], data[rt << 1 | 1]);
    }
    void pushdown(int rt, T m) {
        if (lazy[rt] == 0) return;
        lazy[rt << 1] += lazy[rt];
        lazy[rt << 1 | 1] += lazy[rt];
        if (type == 0) {
            data[rt << 1] += (m - (m >> 1)) * lazy[rt];
            data[rt << 1 | 1] += (m >> 1) * lazy[rt];
        } else if (type == 1) {
            data[rt << 1] += lazy[rt];
            data[rt << 1 | 1] += lazy[rt];
        }
        lazy[rt] = 0;
    }
public:
    SegmentTree(int n, int t) : data((T *)malloc((n << 3) * sizeof(T))), lazy((T *)malloc((n << 3) * sizeof(T))), type(t) {}
    void Build(T * base, int l, int r, int rt) {
        lazy[rt] = 0;
        if (l == r) data[rt] = base[l];
        else {
            int mid = (l + r) >> 1;
            Build(base, l, mid, rt << 1);
            Build(base, mid + 1, r, rt << 1 | 1);
            pushup(rt);
        }
    }
    void Modify(int l, int r, int rt, int L, int R, T v) {
        if (L <= l && R >= r) {
            lazy[rt] += v;
            if (type == 0)
                data[rt] += v * (r - l + 1);
            else if (type == 1)
                data[rt] += v;
            return;
        }
        pushdown(rt, r - l + 1);
        int mid = (l + r) >> 1;
        if (L <= mid)
            Modify(l, mid, rt << 1, L, R, v);
        if (R > mid)
            Modify(mid + 1, r, rt << 1 | 1, L, R, v);
        pushup(rt);
    }
    T QueryPoint(int l, int r, int rt, int val) {
        if (l == r) return data[rt];
        pushdown(rt, r - l + 1);
        int mid = (l + r) >> 1;
        T ret = 0;
        if (val <= mid) ret = QueryPoint(l, mid, rt << 1, val);
        else ret = QueryPoint(mid + 1, r, rt << 1 | 1, val);
        pushup(rt);
        return ret;
    }
    T QuerySegment(int l, int r, int rt, int L, int R) {
        pushdown(rt, r - l + 1);
        if (L == l && R == r) return data[rt];
        int mid = (l + r) >> 1;
        if (R <= mid) return QuerySegment(l, mid, rt << 1, L, R);
        if (mid < L) return QuerySegment(mid + 1, r, rt << 1 | 1, L, R);
        if (type == 0)
            return QuerySegment(l, mid, rt << 1, L, mid) + QuerySegment(mid + 1, r, rt << 1 | 1, mid + 1, R);
        else if (type == 1)
            return max(QuerySegment(l, mid, rt << 1, L, mid), QuerySegment(mid + 1, r, rt << 1 | 1, mid + 1, R));
    }
    int find(int l, int r, int rt, int p, T x) {
        if (r <= p) return -1;
        if (data[rt] < x) return -1;
        if (l == r) return l;
        int mid = (l + r) >> 1;
        if (l > p) {
            if (data[rt << 1] >= x) return find(l, mid, rt << 1, p, x);
            else return find(mid + 1, r, rt << 1 | 1, p, x);
        }
        int rtn = find(l, mid, rt << 1, p, x);
        if (rtn != -1) return rtn;
        return find(mid + 1, r, rt << 1 | 1, p, x);
    }
};
SegmentTree<lint> Tsum(250000, 0), Tmax(250000, 1);


int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    //makedata();
    std::ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> q;
    for (int i = 1; i <= n; i++) cin >> a[i];
    Tsum.Build(a, 1, n, 1);
    Tmax.Build(a, 1, n, 1);
    while (q--) {
        int p;
        lint x;
        cin >> p >> x;
        Tsum.Modify(1, n, 1, p, p, x - a[p]);
        Tmax.Modify(1, n, 1, p, p, x - a[p]);
        a[p] = x;
        if (a[1] == 0) {
            cout << 1 << endl;
            continue;
        }
        int m = 1;
        while (1) {
            lint sum = Tsum.QuerySegment(1, n, 1, 1, m);
            int nex = Tmax.find(1,n,1,m,sum);
            if (nex == -1) {
                cout << -1 << endl;
                break;
            }
            if (a[nex] == Tsum.QuerySegment(1, n, 1, 1, nex - 1)) {
                cout << nex << endl;
                break;
            }
            m = nex;
        }
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/dramstadt/p/9234372.html