HDU 5517 (ACM 2015 沈阳) Triple [树状数组]
2015-11-02 21:07
393 查看
题意:给你N个二元组,M个三元组,在二元组与三元组的最后一个数相同时,两者去掉最后一个数,用剩下的三个数拼凑出一个新的三元组<X,Y,Z>,求这些三维坐标的上凸面的点数。
范围:N,M<=10W,拼凑出来的三元组的X,Y,Z的X<=10W,Y,Z<=1000
解法:很容易发现Y,Z的坐标很小,即变成了求按X排序后,求Y,Z右上方是否还有点,如果没有点了,说明这个点是上凸的点。这个过程可以用二维树状数组完成。当然之前有一个贪心过程,就是对应最后一个数相同的时候,X要取前面二元组中最大的,且需要记录一下取最大值的二元组的数量,最后一旦发现点上凸,加上这个记录的数量即可。
代码:
注意代码中的<X,Y,Z>对应着题目意思的<Y,Z,X>,为了少写一个重载orz
范围:N,M<=10W,拼凑出来的三元组的X,Y,Z的X<=10W,Y,Z<=1000
解法:很容易发现Y,Z的坐标很小,即变成了求按X排序后,求Y,Z右上方是否还有点,如果没有点了,说明这个点是上凸的点。这个过程可以用二维树状数组完成。当然之前有一个贪心过程,就是对应最后一个数相同的时候,X要取前面二元组中最大的,且需要记录一下取最大值的二元组的数量,最后一旦发现点上凸,加上这个记录的数量即可。
代码:
注意代码中的<X,Y,Z>对应着题目意思的<Y,Z,X>,为了少写一个重载orz
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<iostream> #include<stdlib.h> #include<set> #include<map> #include<queue> #include<vector> #include<bitset> #pragma comment(linker, "/STACK:1024000000,1024000000") template <class T> bool scanff(T &ret){ //Faster Input char c; int sgn; T bit=0.1; if(c=getchar(),c==EOF) return 0; while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar(); sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0'); while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0'); if(c==' '||c=='\n'){ ret*=sgn; return 1; } while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10; ret*=sgn; return 1; } #define inf 1073741823 #define llinf 4611686018427387903LL #define PI acos(-1.0) #define lth (th<<1) #define rth (th<<1|1) #define rep(i,a,b) for(int i=int(a);i<=int(b);i++) #define drep(i,a,b) for(int i=int(a);i>=int(b);i--) #define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next) #define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++) #define mem(x,val) memset(x,val,sizeof(x)) #define mkp(a,b) make_pair(a,b) #define findx(x) lower_bound(b+1,b+1+bn,x)-b #define pb(x) push_back(x) using namespace std; typedef long long ll; typedef pair<int,int> pii; #define lowbit(x) (x&(-x)) #define NN 100100 struct node{ int x,y,z,cot; bool operator < (const node temp)const{ return z<temp.z; } }a[NN],b[NN]; int n,m; int la[NN],ra[NN],lb[NN],rb[NN]; int c[1010][1010]; void add(int i,int j){ for(int x=i;x<=1000;x+=lowbit(x)) for(int y=j;y<=1000;y+=lowbit(y)){ c[x][y]++; } } int getsum(int i,int j){ int sum=0; for(int x=i;x>0;x-=lowbit(x)) for(int y=j;y>0;y-=lowbit(y)){ sum+=c[x][y]; } return sum; } map<pii,int> mp; int main(){ tdata{ scanff(n);scanff(m); rep(i,1,n){ scanff(a[i].y); scanff(a[i].z); } rep(i,1,m){ scanff(b[i].x); scanff(b[i].y); scanff(b[i].z); b[i].x=1001-b[i].x; b[i].y=1001-b[i].y; } sort(a+1,a+1+n); sort(b+1,b+1+m); mem(la,0);mem(ra,0);mem(lb,0);mem(rb,0);mem(c,0); rep(i,1,n){ if(i==1||a[i].z!=a[i-1].z)la[a[i].z]=i; if(i==n||a[i].z!=a[i+1].z)ra[a[i].z]=i; } rep(i,1,m){ if(i==1||b[i].z!=b[i-1].z)lb[b[i].z]=i; if(i==m||b[i].z!=b[i+1].z)rb[b[i].z]=i; } rep(i,1,100000){ if(lb[i]==0)continue; if(la[i]==0){ rep(j,lb[i],rb[i]){ b[j].z=0; b[j].cot=0; } continue; } int maxx=-inf,cot=0; rep(j,la[i],ra[i]){ if(a[j].y==maxx)cot++; else if(a[j].y>maxx){ cot=1; maxx=a[j].y; } } rep(j,lb[i],rb[i]){ b[j].z=maxx; b[j].cot=cot; } } sort(b+1,b+1+m); ll ans=0; drep(i,m,1){ if(i==1||b[i].z!=b[i-1].z){ mp.clear(); rep(j,i,m){ mp[mkp(b[j].x,b[j].y)]++; add(b[j].x,b[j].y); if(j==m||b[j].z!=b[j+1].z)break; } rep(j,i,m){ if(getsum(b[j].x,b[j].y)-mp[mkp(b[j].x,b[j].y)]==0){ ans+=ll(b[j].cot); } if(j==m||b[j].z!=b[j+1].z)break; } } } printf("Case #%d: %lld\n",cas,ans); } return 0; }
相关文章推荐
- 选择器
- 产生随机数
- Linux命令大观
- [Android Lint] xxx is not translated in xxx 的解决方法
- #pragma分析
- 一行排奇数列的HTML排版
- c++中的引用和指针
- LeetCode:Rectangle Area
- 如何在应用中使用地图SDK
- JavaScript中in操作符(for..in)、Object.keys()和Object.getOwnPropertyNames()的区别
- cocos2d-x 进度条实现(被砍)掉血效果
- Lesson 6 Transposition and conjugation
- POJ 2155 Matrix
- mysql配置感悟
- PHP怎么与C语言通信
- scala使用redis client - Jedis
- OC第五天之 Dictionary NSSet 数组排序
- sapi_module_struct 研究(一)
- 【LeetCode从零单刷】House Robber
- RCNN 安装编译与MATLAB2014下问题解决