社区讨论

cdq+树状数组 TLE on #10求助

P4169[Violet] 天使玩偶/SJY摆棋子参与者 2已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@lxr89a6m
此快照首次捕获于
2024/06/23 15:28
2 年前
此快照最后确认于
2024/06/23 18:21
2 年前
查看原帖
TLE on #10
卡在 upd 里了,好像是 x=0,但是不知道哪里传进去的 00
好像 c 都被赋值了,但是在 l=1,r=1172 时,c291=0c_{291} = 0
CPP
#include<bits/stdc++.h>
using namespace std;

struct wyb{
	int x,y,op,q,ans;
}a[1000010],b[1000010],c[1000010];

int mx=-2147483648,n,m,tr[1000010];

extern "C" inline int lowbit(int x){return x&(-x);}
extern "C" inline void upd(int x,int u){
	while(x<=mx){
		tr[x]=max(tr[x],u);
		x+=lowbit(x);
	}
}
extern "C" inline int que(int x){
	int ans=0;
	while(x>0){
		ans=max(ans,tr[x]);
		x-=lowbit(x);
	}
	return ans?ans:-2000000000;
}
inline void cl(int x){
	while(tr[x]){
		tr[x]=0;
		x+=lowbit(x);
	}
}
extern "C" inline void cdq(int l,int r){
	if(l==r)return;
	int mid=(l+r)>>1;
	cdq(l,mid);cdq(mid+1,r);
	int j=l,k=mid+1;
	int p=l;
	while(k<=r){
		while(j<=mid&&b[j].x<=b[k].x){
			if(b[j].op==1)upd(b[j].y,b[j].y+b[j].x);
			c[p++]=b[j++];
			if(c[p-1].y==0)cerr<<l<<' '<<r<<' '<<p-1<<' '<<(int)(p==r+1)<<'\n';
		}
		if(b[k].op==2){
			a[b[k].q].ans=min(a[b[k].q].ans,b[k].x+b[k].y-que(b[k].y));
		}
		c[p++]=b[k++];
		if(c[p-1].y==0)cerr<<l<<' '<<r<<' '<<p-1<<' '<<(int)(p==r+1)<<'\n';
	}
	for(int i=l;i<=j-1;i++){
		if(b[i].op==1)cl(b[i].y);
	}
	while(j<=mid){
		c[p++]=b[j++];
		if(c[p-1].y==0)cerr<<l<<' '<<r<<' '<<p-1<<' '<<(int)(p==r+1)<<'\n';
	}
	for(int i=l;i<=r;i++){
		b[i]=c[i];
	}
}
inline void wk(int p1,int p2){
	for(int i=1;i<=n+m;i++){
		b[i]=a[i];
		if(p1)b[i].x=mx-b[i].x;
		if(p2)b[i].y=mx-b[i].y;
	}
	cdq(1,n+m);
}

int main(void){
	#ifdef PAIMON
		freopen("P4169_10.in","r",stdin);
		freopen("4169.ans","w",stdout);
	#endif
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		int x,y;cin>>x>>y;
		a[i].x=++x;a[i].y=++y;
		a[i].q=i;a[i].op=1;
		mx=max(mx,max(x,y));
	}
	for(int i=1;i<=m;i++){
		int op,x,y;cin>>op>>x>>y;
		a[i+n].op=op;a[i+n].x=++x;a[i+n].y=++y;a[i+n].q=i+n;
		a[i+n].ans=0x7fffffff;
		mx=max(mx,max(x,y));
	}
	mx++;
	wk(0,0);wk(1,0);wk(0,1);wk(1,1);
	for(int i=1;i<=m;i++){
		if(a[n+i].op==2)cout<<a[n+i].ans<<'\n';
	}
	return 0;
}

回复

4 条回复,欢迎继续交流。

正在加载回复...