给你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;
}