1. 程式人生 > >hdu 5517 Triple(二維樹狀數組)

hdu 5517 Triple(二維樹狀數組)

題解 printf -- 二維樹狀數組 貢獻 ffd 最大的 lose col

題目鏈接: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\n",++cas,ans); 77 } 78 return 0; 79 }
View Code

hdu 5517 Triple(二維樹狀數組)