题面比较恶心,不过题意就是三元组去重之后,问你有多少个三元组
没有任何一个三元组,三个参数都大于等于它的三个参数
按照一维排序,另外两维只有1000,直接二维树状数组即可,或者线段树也行
线段树的话就是一维当作线段树上的点,然后求这一维大于等于他的区间里,有没有比第三维大的
傻逼去重写错了,检查了一辈子
代码:
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
#define MAX 200005
#define MAXN 1000005
#define maxnode 15
#define sigma_size 30
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lrt rt<<1
#define rrt rt<<1|1
#define middle int m=(r+l)>>1
#define LL long long
#define ull unsigned long long
#define mem(x,v) memset(x,v,sizeof(x))
#define lowbit(x) (x&-x)
#define pii pair<int,int>
#define bits(a) __builtin_popcount(a)
#define mk make_pair
#define limit 10000
//const int prime = 999983;
const int INF = 0x3f3f3f3f;
const LL INFF = 0x3f3f;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-8;
const int mod = 1e9+7;
const ull mx = 133333331;
/*****************************************************/
inline void RI(int &x) {
char c;
while((c=getchar())<'0' || c>'9');
x=c-'0';
while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0';
}
/*****************************************************/
int pre[MAX];
int num[MAX];
map<pair<pii,int>,int> ma;
struct Node{
int a,b,c;
LL num;
bool operator < (const Node &e)const{
if(a==e.a){
if(b==e.b) return c>e.c;
return b>e.b;
}
return a>e.a;
}
}p[MAX];
int maxv[MAX<<2];
void pushup(int rt){
maxv[rt]=max(maxv[lrt],maxv[rrt]);
}
void build(int l,int r,int rt){
if(l==r){
maxv[rt]=0;
return;
}
middle;
build(lson);
build(rson);
pushup(rt);
}
void update(int l,int r,int rt,int pos,int d){
if(l==r){
maxv[rt]=max(maxv[rt],d);
return;
}
middle;
if(pos<=m) update(lson,pos,d);
else update(rson,pos,d);
pushup(rt);
}
int query(int l,int r,int rt,int L,int R){
if(L<=l&&r<=R) return maxv[rt];
middle;
int ans=0;
if(L<=m) ans=max(ans,query(lson,L,R));
if(R>m) ans=max(ans,query(rson,L,R));
return ans;
}
int main(){
//freopen("in.out","r",stdin);
int t,kase=0;
cin>>t;
while(t--){
int n,m;
cin>>n>>m;
mem(pre,0);
mem(num,0);
ma.clear();
for(int i=0;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
if(pre[b]<a){
pre[b]=a;
num[b]=1;
}
else if(pre[b]==a) num[b]++;
}
int tot=0;
for(int i=0;i<m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(pre[c]) p[tot++]=(Node){pre[c],a,b,num[c]};
}
sort(p,p+tot);
int len=0;
p[len++]=p[0];
for(int i=1;i<tot;i++){
if(p[i].a==p[len-1].a&&p[i].b==p[len-1].b&&p[i].c==p[len-1].c) p[len-1].num+=p[i].num;
else p[len++]=p[i];
}
tot=len;
build(1,1000,1);
LL ans=0;
for(int i=0;i<tot;i++){
int ret=query(1,1000,1,p[i].b,1000);
if(ret<p[i].c) ans+=p[i].num;
update(1,1000,1,p[i].b,p[i].c);
}
kase++;
printf("Case #%d: ",kase);
cout<<ans<<endl;
}
return 0;
}