atcoder_official's blog

By atcoder_official, history, 2 months ago, In English

We will hold AtCoder Regular Contest 215.

We are looking forward to your participation!

  • Vote: I like it
  • +22
  • Vote: I do not like it

»
2 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

A kind of "human wise" solution: create a queue to save the "possible surname"'s index, then consider the front of the queue,check every i that satisfies max(1,front-100)<=i<=min(front+100,n) and !(a[i].x<a[fr].x&&a[i].y<a[fr].y&&a[i].z<a[fr].z),push i into the queue. so the answer is the number of i that i haven't entered the queue.

to my surprise,this obviously wrong solution can exactly solve the problem! and it's not too slow(161 ms)!

code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
int n;
struct node{
	int x,y,z;
	int id;
}a[maxn];
bool cmp(node x,node y){
    if(x.x!=y.x)return x.x<y.x;
    if(x.y!=y.y)return x.y<y.y;
    return x.z<y.z;
}
bool vis[maxn];
void solve(){
	cin>>n;
	int id=0;
	for(int i=1;i<=n;i++){
		cin>>a[i].x>>a[i].y>>a[i].z;
		vis[i]=0;
	}
	sort(a+1,a+n+1,cmp);
	vis[n]=1;
	queue<int> q2;
	q2.push(n);
	while(!q2.empty()){
        int fr=q2.front();
        q2.pop();
        for(int i=min(fr+100,n);i>=1&&i>=fr-100;i--){
            if(i==fr)continue;
            if(a[i].x<a[fr].x&&a[i].y<a[fr].y&&a[i].z<a[fr].z)continue;
            if(!vis[i]){
                vis[i]=1;
                q2.push(i);
            }
        }
	}
	int ans=0;
	for(int i=1;i<=n;i++)ans+=vis[i];
	cout<<ans<<"\n";
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int T;
	cin>>T;
	while(T--)solve();
	return 0;
}