zoukankan      html  css  js  c++  java
  • hdu 5517 Triple(二维树状数组)

    HDU 5517

    题目:给出一种有三个元素的顺序,这个数据定义一种偏序,当且仅当一个三元数的所有元素都大于等于另一个时这个数比另一个大.求这个一个集合中不比任何数小的三元数有多少个.

    思路:首先排序去重,此时第一维有序,不用考虑,然后只有不存在比当前数的另外两维都大的数时当前数是可选的,用二位树装数组维护这个信息即可.

    /*
    * @author:  Cwind
    */
    #include <bits/stdc++.h>
    
    using namespace std;
    #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
    #define pb push_back
    #define PB pop_back
    #define bk back()
    #define fs first
    #define se second
    #define sq(x) (x)*(x)
    #define eps (1e-4)
    #define INF (1000000300)
    #define clr(x) memset((x),0,sizeof (x))
    #define cp(a,b) memcpy((a),(b),sizeof (b))
    
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> P;
    
    const int maxn=1e5+400;
    struct tri{
        int a,b,c;
        ll cnt;
        tri(int a,int b,int c,ll cnt):a(a),b(b),c(c),cnt(cnt){}
        tri(){}
        bool operator < (const tri &C)const{
            if(a!=C.a) return a>C.a;
            if(b!=C.b) return b>C.b;
            return c>C.c;
        }
        bool operator != (const tri &C)const{
            return !(a==C.a&&b==C.b&&c==C.c);
        }
    };
    const int maxv=1005;
    struct BIT2D{
        int a[maxv][maxv];
        void add(int x,int y){
            for(;x<maxv;x+=x&-x)
                for(int i=y;i<maxv;i+=i&-i) a[x][i]++;
        }
        int sum(int x,int y){
            int ans=0;
            for(;x>0;x-=x&-x)
                for(int i=y;i>0;i-=i&-i) ans+=a[x][i];
            return ans;
        }
        void clear(){clr(a);}
    }B;
    tri ans[maxn];
    int h;
    int t;
    int n,m;
    P A[maxn];
    void init(){
        clr(A);B.clear();
        h=0;
    }
    int cas;
    int main(){
        freopen("/home/slyfc/CppFiles/in","r",stdin);
        //freopen("/home/slyfc/CppFiles/out","w",stdout);
        cin>>t;
        while(t--){
            init();
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++){
                int a,b;
                scanf("%d%d",&a,&b);
                if(A[b].fs==0||A[b].fs<a) A[b]=P(a,1);
                else if(A[b].fs==a) A[b].se++;     
            }
            for(int i=0;i<m;i++){
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                if(A[c].fs)
                    ans[h++]=tri(A[c].fs,a,b,A[c].se);
            }
            int f=-1;
            sort(ans,ans+h);
            for(int i=0;i<h;i++){
                if(f==-1||ans[f]!=ans[i]) ans[++f]=ans[i];
                else ans[f].cnt+=ans[i].cnt;
            }
            int cnt=0;
            for(int i=0;i<=f;i++){
                int s1=B.sum(ans[i].b-1,maxv-1);
                int s2=B.sum(maxv-1,ans[i].c-1);
                int s3=B.sum(ans[i].b-1,ans[i].c-1);
                int s4=B.sum(maxv-1,maxv-1);
                if(s4-s1-s2+s3==0) cnt+=ans[i].cnt;
                B.add(ans[i].b,ans[i].c);
            }
            printf("Case #%d: %d
    ",++cas,cnt);
        }
        return 0;    
    }
    View Code
  • 相关阅读:
    Docker Private Registry
    Dockerfile
    docker存储卷
    392. 判断子序列
    1576. 替换所有的问号
    270. 最接近的二叉搜索树值
    292. Nim 游戏
    680. 验证回文字符串 Ⅱ
    876. 链表的中间结点
    543. 二叉树的直径
  • 原文地址:https://www.cnblogs.com/Cw-trip/p/4954012.html
Copyright © 2011-2022 走看看