BZOJ 1588 [HNOI2002] 营业额统计

来源:互联网 发布:淘宝怎么截图返现 编辑:程序博客网 时间:2024/05/21 02:22

直接用SPLAY的get_pre()求前驱,get_next()求后继,然后比较大小,求出总和即可。

貌似这题的输入有点问题,我一开始WA,后来去看了别人的DISCUSS,发现输入地方有点坑。

#include <iostream>#include <cstdio>#include <algorithm>#include <string>#include <cmath>#include <cstring>#include <queue>#include <set>#include <vector>#include <stack>#include <map>#include <iomanip>#define PI acos(-1.0)#define Max 2505#define inf 1<<28#define LL(x) (x<<1)#define RR(x) (x<<1|1)#define REP(i,s,t) for(int i=(s);i<=(t);++i)#define ll long long#define mem(a,b) memset(a,b,sizeof(a))#define mp(a,b) make_pair(a,b)#define PII pair<int,int>using namespace std;inline void RD(int &ret) {    char c;    int flag = 1 ;    do {        c = getchar();    } while(c < '0' || c > '9') ;    ret = c - '0';    while((c=getchar()) >= '0' && c <= '9')        ret = ret * 10 + ( c - '0' );    ret *= flag ;}int ch[1111111][2] , num[1111111] , fa[1111111] , data[11111111] ;int root , tot ;void rotate(int x ,int kind) { //kind = 0 ,左旋,kind = 1 ,右旋    int y = fa[x] ;    ch[y][!kind] = ch[x][kind] ;    fa[ch[x][kind]] = y ;    if(fa[y])ch[fa[y]][ch[fa[y]][1] == y] = x ;    fa[x] = fa[y] ;    ch[x][kind] = y ;    fa[y] = x ;}void Splay(int x ,int s ) { //将节点x转到节点s下面    while(fa[x] != s) {        if(fa[fa[x]] == s)rotate(x ,ch[fa[x]][0] == x) ;        else {            int y = fa[x] ;            int z = fa[y] ;            int kind = ( ch[z][0] == y );            if(ch[y][kind] == x) {                rotate(x ,!kind) ;                rotate(x , kind) ;            } else {                rotate(y , kind ) ;                rotate(x , kind ) ;            }        }    }    if(s == 0)root = x ;}void newNode(int& x ,int k ,int father) {    x = ++ tot ;    ch[x][0] = ch[x][1] = 0 ;    data[x] = k ;    fa[x] = father ;}int insert(int k) {    int r = root ;    while(ch[r][data[r] < k]) {        if(data[r] == k) {//避免重复插入            Splay(r ,0 ) ;            return 0 ;        }        r = ch[r][data[r] < k ] ;    }    newNode(ch[r][data[r] < k] , k , r ) ;    Splay(ch[r][data[r] < k ] , 0 ) ;    return 1 ;}int get_pree(int k) {    int d = ch[k][0] ;    if(d == 0)return -1 ;//没有前驱    while(ch[d][1]) {        d = ch[d][1] ;    }     return d ;}int get_next(int k) {    int d = ch[k][1] ;    if(d == 0)return -1 ;//没有后继    while(ch[d][0]) {        d = ch[d][0] ;    }    return d ;}int main() {#ifndef ONLINE_JUDGE    freopen("D:\\acm.txt" , "r" , stdin) ;#endif    int n ;    while(cin >> n) {        int ans = 0 ;        int a ;        root = tot = 0 ;        for (int i = 1 ; i <= n ; i ++ ) {            if(scanf("%d",&a) == EOF) a = 0 ;//这样输入才能A,直接scanf("%d",&a)就WA了,费解。好吧,据说是因为数据丢失。            if(i == 1) {                ans += a ;                newNode(root ,a, 0) ;                continue ;            }            if(insert(a) == 0)continue ;            int a1 = get_next(root) ;            int a2 = get_pree(root) ;            if(a1 == -1)ans += abs(a - data[a2] ) ;            else if(a2 == -1)ans += abs(a - data[a1] ) ;            else ans += min(abs(data[a1] - data[root]) ,abs(data[root] - data[a2]))  ;        }        cout << ans << endl;    }    return 0 ;}


原创粉丝点击