G. 24 观察 + 树状数组

http://codeforces.com/gym/101257/problem/G

首先要看到题目,题目是本来严格大于score[i] > score[j]。然后score[i] < score[j],的才算做是贡献。

然后这题需要一个小观察,就是只有低分的,不fail,然后高分的,fail了,才会交换位置。

也就是平时打比赛,别人fail了,我不fail,我才和它交换位置。(居然这种思维我都没。T_T)

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 1e5 + 40;
int a[maxn];
double p[maxn];
vector<int>vc;
vector<int>id;
double c[maxn];
int lowbit(int x) {
    return x & (-x);
}
void upDate(int pos, double val) {
    assert(pos != 0);
    while (pos <= maxn - 20) {
        c[pos] += val;
        pos += lowbit(pos);
    }
}
double ask(int pos) {
    assert(pos >= 0);
    double ans = 0;
    while (pos) {
        ans += c[pos];
        pos -= lowbit(pos);
    }
    return ans;
}
void work() {
    int n, be;
    scanf("%d%d", &n, &be);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
        a[i]++;
    }
    for (int i = 1; i <= n; ++i) {
        scanf("%lf", &p[i]);
    }
    double ans = 0;
    for (int i = 1; i <= n; ++i) {
        ans += (1 - p[i]) * ask(a[i] - 1);
        if (i != n && a[i] == a[i + 1]) {
            vc.push_back(a[i] - be);
            id.push_back(i);
        } else {
            for (int j = 0; j < vc.size(); ++j) {
                upDate(vc[j], p[id[j]]);
            }
            vc.clear();
            id.clear();
            upDate(a[i] - be, p[i]);
        }
    }
    printf("%0.10f\n", ans);
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    work();
    return 0;
}
View Code

 

posted on 2017-02-18 21:04  stupid_one  阅读(145)  评论(0编辑  收藏  举报

导航