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

    题目链接:hdu 5517 Triple

    题意:

    有n个两元组A,有m个三元组B,然后set C有一个计算方式。

    现在让你找set TOP的size。

    题解:

    理解题意后,显然对于每个b的分组,只有最大的a才有贡献,

    然后就可以发现set B中每个元素按照e分组后,只会对应一个a,所以最多有1e5个三元组可能有贡献。

    然后将这个三元组排一下序,用二维树状数组搞搞就行了。

     1 #include<bits/stdc++.h>
     2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
     3 using namespace std;
     4 typedef long long ll;
     5 
     6 const int N=1e5+7;
     7 int t,n,m,tot,cas,A[N],C[N];
     8 int c[1007][1007];
     9 
    10 int sum(int x,int y)
    11 {
    12     int ret = 0;
    13     for(int i = x;i > 0;i -= i&-i)
    14         for(int j = y;j > 0;j -= j&-j)
    15             ret += c[i][j];
    16     return ret;
    17 }
    18 void add(int x,int y,int val)
    19 {
    20     for(int i = x;i <= 1003;i += i&-i)
    21         for(int j = y;j <= 1003;j += j&-j)
    22             c[i][j] += val;
    23 }
    24 
    25 int ask(int x1,int y1,int x2,int y2)
    26 {
    27     return sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1);
    28 }
    29 
    30 struct Node
    31 {
    32     int a,c,d;
    33     ll cnt;
    34     Node(int _a=0,int _c=0,int _d=0,ll _e=0):a(_a),c(_c),d(_d),cnt(_e){}
    35     bool operator <(const Node &BB)const
    36     {
    37         if(a!=BB.a)return a<BB.a;
    38         if(c!=BB.c)return c<BB.c;
    39         return d<BB.d;
    40     }
    41 }have[N];
    42 
    43 
    44 int main(){
    45     scanf("%d",&t);
    46     while(t--)
    47     {
    48         F(i,1,100000)A[i]=0;
    49         memset(c,0,sizeof(c)),tot=0;
    50         scanf("%d%d",&n,&m);
    51         int a,b,c;
    52         F(i,1,n)
    53         {
    54             scanf("%d%d",&a,&b);
    55             if(a>A[b])A[b]=a,C[b]=0;
    56             if(a==A[b])C[b]++;
    57         }
    58         F(i,1,m)
    59         {
    60             scanf("%d%d%d",&a,&b,&c);
    61             if(A[c])have[++tot]=Node(A[c],a,b,C[c]);
    62         }
    63         sort(have+1,have+1+tot);
    64         int tcnt=1;
    65         F(i,2,tot)if(have[i].a==have[tcnt].a&&have[i].c==have[tcnt].c&&have[i].d==have[tcnt].d)
    66         {
    67             have[tcnt].cnt+=have[i].cnt;
    68         }else have[++tcnt]=have[i];
    69         ll ans=0;tot=tcnt;
    70         for(int i=tot;i;i--)
    71         {
    72             if(!ask(have[i].c,have[i].d,1000,1000))
    73                 ans+=have[i].cnt;
    74             add(have[i].c,have[i].d,1);
    75         }
    76         printf("Case #%d: %lld
    ",++cas,ans);
    77     }
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    剖析VC++函数调用约定转
    C++的坑真的多吗?转
    An Introduction to LockFree Programming转
    __cdecl __stdcall区别转
    学习PHP感谢帅哥分享O(∩_∩)O~
    28个Unix/Linux的命令行神器转
    C++ 对象的内存布局(上)转
    一个fork的面试题转
    20本最好的Linux免费书籍转
    谁说外国人都很文明
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7517749.html
Copyright © 2011-2022 走看看