Codeforces Beta Round #79 (Div. 1 Only) B. Buses 树状数组

http://codeforces.com/contest/101/problem/B

给定一个数n,起点是0  终点是n,有m两车,每辆车是从s开去t的,我们只能从[s,s+1,s+2....t-1]处上车,从t处下车。,

问能否去到点n,求方案数

设L[x]表示有多少辆车能够到达x处。

只能从t处下车:说明只能单点更新,对于没辆车x,在区间[s,s+1,s+2....t-1]内上车是可以得,那么有多少辆车呢?明显就是∑区间里能到达的点。然后单点更新t即可

数据大,明显不能到达的点是没用的,离散化一下即可。

坑点就是:因为车是无序的,所以应该优先处理最快下车的点。这样就能对后面进行更新

注意树状数组哪里也要取模

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
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>
const int maxn = 3e5 + 20;
const int MOD = 1e9 + 7;
int n, to;
LL c[maxn];
int lowbit (int x) {
    return x&(-x);
}
void add (int pos,LL val) {
    while (pos<=to + 20) {
        c[pos] += val;
        c[pos] %= MOD;
        pos += lowbit(pos);
    }
    return ;
}
LL get_sum (int pos) {
    LL ans = 0;
    while (pos) {
        ans += c[pos];
        ans %= MOD;
        pos -= lowbit(pos);
    }
    return ans;
}
struct node {
    int s, t;
}a[maxn];
bool cmp (node a, node b) {
    if (a.t != b.t) {
        return a.t < b.t;
    } else {
        return a.s < b.s;
    }
}
set<int>ss;
map<int,int>pos;
LL ways[maxn];
void work() {
    cin >> n;
    int m;
    cin >> m;
    int numzero = 0;
    int numlast = 0;
    for (int i = 1; i <= m; ++i) {
        scanf("%d%d", &a[i].s, &a[i].t);
        if (a[i].s == 0) numzero++;
        if (a[i].t == n) numlast++;
    }
    if (numzero == 0 || numlast == 0) {
        cout << "0" << endl;
        return;
    }
    sort(a + 1, a + 1 + m, cmp);
    for (int i = 1; i <= m; ++i) {
        ss.insert(a[i].s);
        ss.insert(a[i].t);
    }
    for (set<int>::iterator it = ss.begin(); it != ss.end(); ++it) {
        if (pos[*it] == 0) {
            pos[*it] = ++to;
        }
    }
    add(1, 1);
    for (int i = 1; i <= m; ++i) {
        int toa = pos[a[i].s];
        int tob = pos[a[i].t];
        LL t = (get_sum(tob - 1) - get_sum(toa - 1) + MOD) % MOD;
        add(tob, t);
    }
    LL ans = get_sum(pos[n]) - get_sum(pos[n] - 1);
    if (ans < 0) ans += MOD;
    cout << ans << endl;
}
int main() {
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    work();
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/liuweimingcprogram/p/5874918.html