[CF641E]Little Artem and Time Machine

Little Artem and Time Machine

题解

很水的一道CDQ。

很容易发现这是一道三维偏序:操作顺序,时间轴与x的值。

由于操作顺序这一维是已经排好序的了,我们可以不去动它,再按照第二维进行CDQ。

按照第二维分治时通过操作的状态将左区间的操作影响添加到右区间上。

因为它只在x_{i}=x_{j}时才会产生影响,我们需要用桶将其记录下来。因为需要用桶,所以在开始的时候还需要进行一次离散化。

源码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
using namespace std;
#define lowbit(x) (x&-x)
#define MAXN 100010
typedef long long LL;
#define int LL
typedef pair<int,int> pii;
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
struct ming{int typ,t,x,id,pos;}a[MAXN];
int n,ans[MAXN],num[MAXN];
vector<int> vec;
int cmp1(const ming &a,const ming &b){return a.t<b.t;}
int cmp2(const ming &a,const ming &b){return a.id<b.id;}
void merge(int l,int r){
	if(l==r)return ;int mid=l+r>>1,j=l;
	merge(l,mid);merge(mid+1,r);
	sort(a+l,a+mid+1,cmp1);
	sort(a+mid+1,a+r+1,cmp1);
	for(int i=mid+1;i<=r;i++){
		while(j<=mid&&a[j].t<=a[i].t)
			num[a[j].pos]+=a[j].typ,j++;
		if(!a[i].typ)ans[a[i].id]+=num[a[i].pos];
	}
	for(int i=l;i<j;i++)num[a[i].pos]-=a[i].typ;
}
signed main(){
	read(n);
	for(int i=1;i<=n;i++){
		read(a[i].typ);read(a[i].t);read(a[i].x);
		if(a[i].typ==2)a[i].typ=-1;
		if(a[i].typ==3)a[i].typ=0;
		a[i].id=i;vec.push_back(a[i].x);
	}
	sort(vec.begin(),vec.end());
	vec.erase(unique(vec.begin(),vec.end()),vec.end());
	for(int i=1;i<=n;i++)a[i].pos=lower_bound(vec.begin(),vec.end(),a[i].x)-vec.begin()+1;
	merge(1,n);sort(a+1,a+n+1,cmp2);
	for(int i=1;i<=n;i++)if(!a[i].typ)printf("%lld\n",ans[i]);
	return 0;
}

谢谢!!!

原创文章 123 获赞 166 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Tan_tan_tann/article/details/105972963