Codeforces Beta Round #12 (Div 2 Only) D. Ball 树状数组查询后缀、最值

http://codeforces.com/problemset/problem/12/D

这里的BIT查询,指的是查询[1, R]或者[R, maxn]之间的最值,这样就够用了。

设三个权值分别是b[1], b[2], b[2];

首先,先把b[1]值离散化,离散成一个个id,那么只能是在id比较大的地方找了。然后把b[2]排序,倒序查询,也就是先查询最大的,当然它是没可能自杀的,因为它已经最大了,然后查询完后,把它压进bit后,以后在bit查询,就不需要管b[2]了,因为在bit里面的b[2]永远都是较大者,其实这是一个常用的方法啦。hack点是相同的值不能提前更新,细节看代码 + 慢慢debug

现在说说bit的作用,bit维护的是b[3],因为我们已经离散化b[1]了,那么每一个元素的下标就相当于离散化的b[1],所以加进去BIT的时候用id做下标即可。bit维护后缀最大值。

hack点的意思是,假如你的a[i].b[2] == a[j].b[2],那么不能在查询a[j]前提前把a[i]加入bit,因为bit查询默认是b[2]成立的,但是提前更新了的话,不成立。

#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>
#include <stack>
const int maxn = 5e5 + 20;
int c[maxn], en;
int lowbit(int x) {
    return x & (-x);
}
void upDate(int pos, int val) {
    while (pos) {
        c[pos] = max(c[pos], val);
        pos -= lowbit(pos);
    }
}
int ask(int pos) {
    int ans = -1;
    while (pos <= en) {
        ans = max(ans, c[pos]);
        pos += lowbit(pos);
    }
    return ans;
}
struct Node {
    int a[5], id;
}a[maxn];
stack<int> st;
bool cmp0(struct Node a, struct Node b) {
    return a.a[1] < b.a[1];
}
bool cmp1(struct Node a, struct Node b) {
    return a.a[2] < b.a[2];
}

void work() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) scanf("%d", &a[i].a[1]);
    for (int i = 1; i <= n; ++i) scanf("%d", &a[i].a[2]);
    for (int i = 1; i <= n; ++i) scanf("%d", &a[i].a[3]);
    sort(a + 1, a + 1 + n, cmp0);
    en = 1;
    a[1].id = en;
    for (int i = 2; i <= n; ++i) {
        if (a[i].a[1] == a[i - 1].a[1]) {
            a[i].id = en;
        } else a[i].id = ++en;
    }
    en += 2;
    memset(c, -1, sizeof c);
    sort(a + 1, a + 1 + n, cmp1);
//    for (int i = 1; i <= n; ++i) {
//        cout << a[i].a[1] << " " << a[i].a[2] << " " << a[i].a[3] << " " << a[i].id << endl;
//    }
    st.push(n);
    int ans = 0;
    for (int i = n - 1; i >= 1; --i) {
        if (a[i].a[2] == a[i + 1].a[2]) {
            st.push(i);
            int res = ask(a[i].id + 1);
            ans += res > a[i].a[3];
        } else {
            while (!st.empty()) {
                int res = st.top();
                st.pop();
                upDate(a[res].id, a[res].a[3]);
            }
            int res = ask(a[i].id + 1);
            ans += res > a[i].a[3];
            st.push(i);
//            upDate(a[i].id, a[i].a[3]);
        }
    }
    cout << ans << endl;
}
int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    work();
    return 0;
}

时间: 2024-12-23 13:40:26

Codeforces Beta Round #12 (Div 2 Only) D. Ball 树状数组查询后缀、最值的相关文章

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即可 数据大,明显不能到达的点是没用的,离

Codeforces Beta Round #12 (Div 2 Only) D. Ball sort/map

D. Ball Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/12/D Description N ladies attend the ball in the King's palace. Every lady can be described with three values: beauty, intellect and richness. King's Master

Codeforces Beta Round #12 (Div 2 Only)

Codeforces Beta Round #12 (Div 2 Only) http://codeforces.com/contest/12 A 水题 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define sqr(x) ((x)*(x)) 6 #define maxn 1000010 7 t

Codeforces Round #301 (Div. 2) E . Infinite Inversions 树状数组求逆序数

E. Infinite Inversions time limit per test 2 seconds memory limit per test 256 megabytes input standard input  output standard output There is an infinite sequence consisting of all positive integers in the increasing order: p = {1, 2, 3, ...}. We pe

Codeforces Beta Round #91 (Div. 1 Only) E. Lucky Array

E. Lucky Array Petya loves lucky numbers. Everybody knows that lucky numbers are positive integers whose decimal representation contains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467are not. Petya has an arra

暴力/DP Codeforces Beta Round #22 (Div. 2 Only) B. Bargaining Table

题目传送门 1 /* 2 题意:求最大矩形(全0)的面积 3 暴力/dp:每对一个0查看它左下的最大矩形面积,更新ans 4 注意:是字符串,没用空格,好事多磨,WA了多少次才发现:( 5 详细解释:http://www.cnblogs.com/cszlg/p/3217478.html 6 */ 7 #include <cstdio> 8 #include <algorithm> 9 #include <cstring> 10 #include <cmath>

图论/暴力 Codeforces Beta Round #94 (Div. 2 Only) B. Students and Shoelaces

题目传送门 1 /* 2 图论/暴力:这是个连通的问题,每一次把所有度数为1的砍掉,把连接的点再砍掉,总之很神奇,不懂:) 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #include <cmath> 8 using namespace std; 9 10 const int MAXN = 1e2 + 10; 11 const int INF = 0x3f3f3

BFS Codeforces Beta Round #94 (Div. 2 Only) C. Statues

题目传送门 1 /* 2 BFS:三维BFS,坐标再加上步数,能走一个点当这个地方在步数内不能落到.因为雕像最多8步就会全部下落, 3 只要撑过这个时间就能win,否则lose 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <queue> 8 #include <vector> 9 #include <cstring> 10 using namespace std; 11 1

水题 Codeforces Beta Round #70 (Div. 2) A. Haiku

题目传送门 1 /* 2 水题:三个字符串判断每个是否有相应的元音字母,YES/NO 3 下午网速巨慢:( 4 */ 5 #include <cstdio> 6 #include <cstring> 7 #include <string> 8 #include <iostream> 9 #include <algorithm> 10 #include <cmath> 11 using namespace std; 12 13 cons