码迷,mamicode.com
首页 > 其他好文 > 详细

【CDQ】 HDU 4742 Pinball Game 3D

时间:2015-10-10 20:02:38      阅读:246      评论:0      收藏:0      [点我收藏+]

标签:

通道

题意:给你n(1e5)个三元组、然后要你求这n个三元组的LIS。和这样LIS的方案数。一个三元祖a比另一个元祖b大的条件是ax>=bx,ay>=by,az>=bz

思路:先按x排序,先降低一维,然后 剩下y 、z,在y上进行CDQ分治,按y的大小用前面的更新后面的。z方向离散化之后用树状数组维护就可以

代码:

技术分享
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+10;
const int mod = 1 << 30;
struct Ball{
    int x,y,z,idx;
    bool operator < (const Ball &rhs)const{
        return x < rhs.x || (x == rhs.x && y < rhs.y) || (x == rhs.x && y == rhs.y && z < rhs.z);
    }
} ball[maxn],tmpball[maxn];

struct DP{
    int len,cnt;
    DP(){}
    DP(int _len,int _cnt):
        len(_len),cnt(_cnt) {}
} dp[maxn],c[maxn];
int vec[maxn],idx;
int color[maxn], C;
inline int lowbit (int x){
    return x & -x;
}
inline void update (DP &dp1, DP &dp2){
    if (dp1.len < dp2.len)
        dp1 = dp2;
    else if (dp1.len == dp2.len)
        dp1.cnt += dp2.cnt;
}
inline void modify(int x,DP &d){
    while (x <= idx){
        if (color[x] != C) color[x] = C,c[x] = DP(0, 0);
        update(c[x],d);
        x += lowbit(x);
    }
}
DP query(int x){
    DP ans = DP (0,0);
    while (x){
        if (color[x] == C) update(ans,c[x]);
        x -= lowbit(x);
    }
    return ans;
}
inline void CLR(int x){
    while (x <= idx){
        c[x] = DP(0,0);
        x += lowbit(x);
    }
}
bool cmp(Ball a, Ball b) {
    if (a.y != b.y) return a.y < b.y;
    return a.idx < b.idx;
}
void CDQ (int l, int r){
    if (l == r)
        return ;
    int mid = (l + r) >> 1;
    CDQ (l, mid);
    for (int i = l; i <= r; i++){
        tmpball[i] = ball[i];
        tmpball[i].x = 0;
    }
   sort(tmpball+l,tmpball+r+1,cmp);
   ++C;
    for (int i = l; i <= r; i++){
        if (tmpball[i].idx <= mid){
            modify(tmpball[i].z,dp[tmpball[i].idx]);
        } else {
            DP tmp = query(tmpball[i].z);
            tmp.len++;
            update(dp[tmpball[i].idx],tmp);
        }
    }
    CDQ (mid+1, r);
}
int main() {
    int T, n;
    scanf ("%d",&T);
    while (T--) {
        scanf ("%d",&n);
        for (int i = 1; i <= n; i++) {
            scanf ("%d%d%d",&ball[i].x, &ball[i].y, &ball[i].z);
            vec[i-1] = ball[i].z;
        }
        sort (ball+1, ball+n+1);
        sort (vec,vec+n);
        idx = unique(vec,vec+n) - vec;
        for (int i = 1; i <= n ; i++) {
            ball[i].z = lower_bound(vec,vec+idx,ball[i].z) - vec + 1;
            ball[i].idx = i;
            dp[i] = DP(1,1);
        }
        CDQ(1,n);
        DP ans = DP(0,0);
        for (int i = 1; i <= n ;i++)
            update(ans,dp[i]);
        printf("%d %d\n",ans.len, ans.cnt % mod);
    }
    return 0;
}
View Code

 

【CDQ】 HDU 4742 Pinball Game 3D

标签:

原文地址:http://www.cnblogs.com/Rojo/p/4868060.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!