hdu 5517二维树状数组

给你n个二元组<a,b>, m个三元组<c,d,e>. 如果d = e,那么<a,c,d>会组成一个新的三元组集合G.
问G中有多少个三元组在凸点.(没有其它三元组比它大)
要注意去重. 因为要求没有其它三元组比它大. 如果同一个b有多个a,那么只需要取最大的即可.
然后通过排序可以解决第一位a. 剩下两位c,d则可以通过二维树状数组来维护是否是最大值.
三元组G中相同的合并.

极其无奈 wa了无数次
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1000;
const int maxn=1e5+100;
int sum[N+10][N+10];
int t,n,m;
struct node{
    int x,y,z,num;
}a[maxn],c[maxn],cc[maxn];
vector<node>b[maxn];
bool cmp(const node &l,const node &r)
{
    if(l.z==r.z)
    {
        if(l.x==r.x)
            return l.y>r.y;
        else
            return l.x>r.x;
    }
    else
    return l.z>r.z;
}

int lowbit(int x) {return x&(-x);}
int update(int x,int y,int val)
{
    for(int i=x;i<=N;i+=lowbit(i))
        for(int j=y;j<=N;j+=lowbit(j))
        sum[i][j]+=val;
}
int query(int x,int y)
{
    int ans=0;
    for(int i=x;i>0;i-=lowbit(i))
        for(int j=y;j>0;j-=lowbit(j))
        ans+=sum[i][j];
    return ans;
}

int main()
{
    freopen("in.txt","r",stdin);
    int val,cas=0;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        memset(a,0,sizeof a);
        memset(c,0,sizeof c);
        for(int i=1;i<=m;i++)
        b[i].clear();
        for(int i=1;i<=n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            if(x==a[y].x)
            a[y].num++;
            else
            if(x>a[y].x)
            {
                a[y].x=max(a[y].x,x);
                a[y].num=1;
            }
        }
        int cnt=0;
        for(int i=1;i<=m;i++)
        {
            node g;
            int z;
            scanf("%d%d%d",&g.x,&g.y,&z);
            if(a[z].num>0)
            {
                 cnt++;
                 c[cnt].x=g.x;
                 c[cnt].y=g.y;
                 c[cnt].z=a[z].x;
                 c[cnt].num=a[z].num;
            }

        }
        sort(c+1,c+cnt+1,cmp);

        int nn=1;
        for(int i=2;i<=cnt;i++)
        {
            if(c[nn].x==c[i].x&&c[nn].y==c[i].y&&c[nn].z==c[i].z)
            {
                c[nn].num+=c[i].num;
            }
            else
            {
                c[++nn]=c[i];
            }
        }



        ll ans=0;
        memset(sum,0,sizeof sum);
        for(int i=1;i<=nn;i++)
        {
            int x=c[i].x,y=c[i].y,num=c[i].num;
         //   if(x==c[i-1].x&&y==c[i-1].y&&c[i].z==c[i-1].z)
        //        continue;
        //    cout<<query(N,N)<<endl;
        //    cout<<query(x-1,N)<<endl;
        //    cout<<query(N,y-1)<<endl;
       //    cout<<query(x-1,y-1)<<endl;
       //     cout<<c[i].z<<"--"<<x<<"--"<<y<<endl;

            if(query(N,N)-query(x-1,N)-query(N,y-1)+query(x-1,y-1)==0)
                ans+=1ll*num;
            update(x,y,1);
       //     cout<<ans<<endl;
       //     puts("-------------------------");
        }

        printf("Case #%d: %lld\n",++cas,ans);
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/dllpxfire/article/details/80303805