CF 1190D Tokitsukaze and Strange Rectangle 離散化+線段樹

思路: 將橫縱座標進行離散化,然後縱座標由大到小就行枚舉(由小到大枚舉會讓代碼變得極其麻煩),對於出現的新點,包含新點的集合則對答案有貢獻.我們考慮有哪些區間不包含新點:假設共有x種橫座標,那麼總區間個數爲x*(x+1)/2,設對於某一特定的y,出現了m個新點,那麼新點的橫座標之間的區間則爲不包含新點的區間,例如,新點的橫座標分別爲 3,5,8 那麼不包含新點的區間則爲[1,2]的所有子區間, [4,4]的所有子區間,[8,橫座標最大值]的所有子區間,所有區間減去子區間即爲新增的集合的個數.

 

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <time.h>
#include <map>
#include <set>
#define mem(a,x) memset(a,x,sizeof(a))
#define gi(x) scanf("%d",&x)
#define gi2(x,y) scanf("%d%d",&x,&y)
#define gi3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define gll(x) scanf("%lld",&x)
#define gll2(x,y) scanf("%lld%lld",&x,&y)
using namespace std;
const double eps=1e-8; 
typedef long long ll;
const int MAXN=200005;
const ll mod=1e9+7;
const int inf=0x3f3f3f3f;
int n;
struct Node{
	int x,y;
}node[MAXN];
struct Tree{
	int val;
	int l,r;
}tree[MAXN<<2];
bool cmp(Node a,Node b){
	if(a.y==b.y)return a.x<b.x;
	return a.y>b.y;
}
map<int,int>ms;

vector<int>x,y,ans,up;
int maxx,maxy;
void build(int l,int r,int i){
	tree[i].l=l;
	tree[i].r=r;
	tree[i].val=0;
	if(l==r){
		return;
	}
	int mid=(l+r)/2;
	build(l,mid,i<<1);
	build(mid+1,r,i<<1|1);
}
int query(int l,int r,int i){
	if(tree[i].l>=l&&tree[i].r<=r){
		return tree[i].val;
	}
	int mid=(tree[i].l+tree[i].r)/2;
	int ans=0;
	if(l<=mid)ans=query(l, r, i<<1);
	if(r>=mid+1)ans+=query(l, r, i<<1|1);
	return ans;
}
void update(int x,int i){
	if(tree[i].l==tree[i].r){
		tree[i].val=1;
		return;
	}
	int mid=(tree[i].l+tree[i].r)/2;
	if(x<=mid){
		update(x, i<<1);
	}
	else update(x,i<<1|1);
	tree[i].val=tree[i<<1].val+tree[i<<1|1].val;
	return ;
}
int book[MAXN];

int main(){
	
	gi(n);
	for(int i=1;i<=n;i++){
		gi2(node[i].x,node[i].y);
		x.push_back(node[i].x);
		y.push_back(node[i].y);
	}
	sort(x.begin(),x.end());
	x.erase(unique(x.begin(),x.end()), x.end());
	for(int i=0;i<x.size();i++){
		ms[x[i]]=i+1;
	}
	for(int i=1;i<=n;i++){
		node[i].x=ms[node[i].x];
	}
	sort(y.begin(),y.end());ms.clear();
	y.erase(unique(y.begin(),y.end()), y.end());
	for(int i=0;i<y.size();i++){
		ms[y[i]]=i+1;
	}
	for(int i=1;i<=n;i++){
		node[i].y=ms[node[i].y];
	}
	maxx=x.size();maxy=y.size();
	build(1,maxx,1);
	sort(node+1,node+n+1,cmp);
	int i=1;
	ll cnt=0;
	ll res=0;
	while(i<=n){
		ans.push_back(1);
		int t=node[i].y;
		while(i<=n&&node[i].y==t){
			int x=book[node[i].x]++;
			if(x==0){
				cnt++;
				up.push_back(node[i].x);
			}
			ans.push_back(node[i].x-1);
			ans.push_back(node[i].x+1);
			i++;
		}
		ans.push_back(maxx);
		ll sum=cnt*(cnt+1)/2;
		for(int i=0;i<ans.size();i+=2){
			int l=ans[i],r=ans[i+1];
			if(l<=r){
				int y=query(l, r, 1);
				sum-=1ll*y*(y+1)/2;
			}
		}
		res+=sum;
		for(int i=0;i<up.size();i++){
			int t=up[i];
			update(t, 1);
		}
		ans.clear();
		up.clear();
	}
	printf("%lld\n",res);

	
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章