hdu 5517 Triple(二维树状数组)

Triple

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 388    Accepted Submission(s): 148


Problem Description
Given the finite multi-set A of n pairs of integers, an another finite multi-set B of m triples of integers, we define the product of A and B as a multi-set

C=AB={a,c,da,bA, c,d,eB and b=e}

For each a,b,cC, its BETTER set is defined as

BETTERC(a,b,c)={u,v,wCu,v,wa,b,c, ua, vb, wc}

As a \textbf{multi-set} of triples, we define the TOP subset (as a multi-set as well) of C, denoted by TOP(C), as

TOP(C)={a,b,cCBETTERC(a,b,c)=}

You need to compute the size of TOP(C).
 

 

Input
The input contains several test cases. The first line of the input is a single integer t (1t10) which is the number of test case. Then t test cases follow.

Each test case contains three lines. The first line contains two integers n (1n105) and m (1m105) corresponding to the size of A and B respectively.
The second line contains 2×n nonnegative integers
a1,b1,a2,b2,,an,bn

which describe the multi-set A, where 1ai,bi105.
The third line contains 3×m nonnegative integers
c1,d1,e1,c2,d2,e3,,cm,dm,em

corresponding to the m triples of integers in B, where 1ci,di103 and 1ei105.
 

 

Output
For each test case, you should output the size of set TOP(C).
 

 

Sample Input
2
5 9
1 1 2 2 3 3 3 3 4 2
1 4 1 2 2 1 4 1 1 1 3 2 3 2 2 4 1 2 2 4 3 3 2 3 4 1 3
3 4
2 7 2 7 2 7
1 4 7 2 3 7 3 2 7 4 1 7
 
Sample Output
Case #1: 5
Case #2: 12

 

/*
hdu 5517 Triple(二维树状数组)

problem:
给你n个二元组<a,b>, m个三元组<c,d,e>. 如果d = e,那么<a,c,d>会组成一个新的三元组集合G.
问G中有多少个三元组在凸点.(没有其它三元组比它大)

solve:
要注意去重. 因为要求没有其它三元组比它大. 如果同一个b有多个a,那么只需要取最大的即可.
然后通过排序可以解决第一位a. 剩下两位c,d则可以通过二维树状数组来维护是否是最大值.
三元组G中相同的合并.

hhh-2016-08-31 20:06:36
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <math.h>
#include <queue>
#include <set>
#include <map>
#define lson  i<<1
#define rson  i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define scanfi(a) scanf("%d",&a)
#define scanfs(a) scanf("%s",a)
#define scanfl(a) scanf("%I64d",&a)
#define key_val ch[ch[root][1]][0]
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const ll mod = 1e9+7;
const int maxn = 100010;
const int maxx = 1050;
int a,b;
int to[maxn],have[maxn];

struct node
{
    int a,b,c;
    int w;
    node(){}
    node(int _a,int _b,int _c,int _w):a(_a),b(_b),c(_c),w(_w) {}
    bool operator <(const node &t)const
    {
        if(a!= t.a)
            return a < t.a;
        else if(b != t.b)
            return b < t.b;
        else if(c != t.c)
            return c < t.c;
    }
    node operator +(const node &t)const
    {
        return node(a,b,c,w+t.w);
    }
    bool operator ==(const node &t)const
    {
        return !(*this<t || t < *this);
    }
};
ll s[maxx][maxx];
int lowbit(int x)
{
    return x&(-x);
}
void add(int x,int y,ll val)
{
    for(int i = x; i <= 1000; i+=lowbit(i))
        for(int j = y; j <= 1000; j+=lowbit(j))
        {
            s[i][j] += val;
        }
}

ll sum(int x,int y)
{
    ll cnt = 0;
    for(int i = x; i > 0; i-=lowbit(i))
        for(int j = y; j > 0; j-=lowbit(j))
        {
            cnt += s[i][j];
        }
    return cnt;
}
node tp[maxn];
int main()
{
    int T,cas =1;
    int c,d,e;
//    freopen("in.txt","r",stdin);
    scanfi(T);
    while(T--)
    {
        int n,m;
        clr(s,0),clr(to,0);
        int Maxy = 0, Maxx = 0,cnt = 0;
        scanfi(n),scanfi(m);
        for(int i = 0; i < n; i++)
        {
            scanfi(a),scanfi(b);
            if(a > to[b])to[b] = a,have[b] = 1;
            else if(a == to[b])have[b] ++;
//            cout << a[i] <<" " <<b[i] <<endl;
        }
        for(int i = 0; i < m; i++)
        {
            scanfi(c),scanfi(d),scanfi(e);
            Maxx = max(Maxx,c);
            Maxy = max(Maxy,d);
            if(to[e])
              tp[cnt++] = node(to[e],c,d,have[e]);
        }
        sort(tp,tp+cnt);
        int tot = 0;
        for(int i = 1;i < cnt;i++)
        {
            if(tp[i] == tp[tot])
            {
                tp[tot] = tp[tot] + tp[i];
            }
            else
            {
                tp[++tot] = tp[i];
            }
        }
        ll ans = 0;
        for(int i = tot;i >= 0;i--)
        {
            node t = tp[i];
//            printf("%d%d%d %d\n",t.a,t.b,t.c,t.w);
            int x = t.b,y = t.c;
            int large = sum(1000,1000)-sum(x-1,1000)-sum(1000,y-1)+sum(x-1,y-1);
//            if(t.a != last)
//                large -= have;
            if(large == 0)
                ans = (ll)(ans+t.w);
            add(x,y,1);
        }
        printf("Case #%d: %I64d\n",cas++,ans);
    }
    return 0;
}

/*
1
3 4
2 7 2 7 2 7
1 4 7 2 3 7 3 2 7 4 1 7
*/

  

posted @ 2016-08-31 20:14  Przz  阅读(498)  评论(0编辑  收藏  举报