P6344 [CCO 2017] Vera 与现代艺术 题解
思路
NOIP 模拟赛考到了,但是只会做特殊性质。
注意到关键性质是对于一个限制 \(x\) 和一个询问 \(r\),那么如果在二进制意义下 \(x\) 的所有较低的位都与 \(r\) 的对应的位一样,那么 \(r\) 就可以被 \(x\) 贡献。
注意到这个是限制较低位的,不太好表示。因此考虑将所有的限制和询问在二进制意义下翻转。这样就变成了限制高位,其低位在高位确定的情况下可以任意取值。这样 \(r\) 的取值范围就变成了一段连续的区间。
具体的,对于一个限制 \(x\),如果 \(r\) 在 \([x-\text{lowbit}(x)+1,x+\text{lowbit}(x)-1]\) 之间,那么 \(r\) 就可以被 \(x\) 贡献。
发现如果是一维限制那就是一个区间加单点查。现在是二维的问题就变成了平面上的矩形加单点查。简单扫描线即可。
code
注意到由于我们是想将高位的限制改成低位的限制,因此我们的翻转统一是按 60 位来反转的,因此一定会超过 int。但是注意到 #define int long long 并不可以对常数生效,因此记得写 1ll!!!(因为这个调了快一个小时)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define lb(x) (x&(-x))
const int N=2e6+7;
int n,m,t[N],ans[N],cnt=0;
struct node{
	int x,y,w,s;
}que[N];
struct edge{
	int l,r,w,s;
};vector <edge> loc[N];
int rev(int x){
	int res=0,tmp=0,len=60;//注意到这里的翻转不是正常意义下的。 
	while(x){
		if(x&1)res|=(1ll<<(len-tmp));//注意到 define 并不对常数生效!!! 
		tmp++,x>>=1;
	}
	return res;
}
namespace bit{
	int tr[N];
	void modify(int x,int w){while(x<=cnt)tr[x]+=w,x+=lb(x);}
	int query(int x){int res=0;while(x)res+=tr[x],x-=lb(x);return res;}
}
using namespace bit;
signed main(){
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	cin>>que[i].x>>que[i].y>>que[i].w,que[i].x=rev(que[i].x),que[i].y=rev(que[i].y),t[++cnt]=que[i].x,t[++cnt]=que[i].y;
	for(int i=1;i<=m;i++)cin>>que[n+i].x>>que[n+i].y,que[n+i].x=rev(que[n+i].x),que[n+i].y=rev(que[n+i].y),t[++cnt]=que[i+n].x,t[++cnt]=que[i+n].y;
	sort(t+1,t+cnt+1);cnt=unique(t+1,t+cnt+1)-(t+1);
	for(int i=1;i<=n;i++){
		int x=que[i].x,y=que[i].y;
		int xl=lower_bound(t+1,t+cnt+1,x-lb(x)+1)-t,xr=upper_bound(t+1,t+cnt+1,x+lb(x)-1)-t-1;
		int yl=lower_bound(t+1,t+cnt+1,y-lb(y)+1)-t,yr=upper_bound(t+1,t+cnt+1,y+lb(y)-1)-t-1;
		loc[xl].push_back({yl,yr,que[i].w,0}),loc[xr+1].push_back({yl,yr,-que[i].w,0});
	}
	for(int i=n+1;i<=n+m;i++){
		int x=lower_bound(t+1,t+cnt+1,que[i].x)-t,y=lower_bound(t+1,t+cnt+1,que[i].y)-t;
		loc[x].push_back({y,y,i-n,1});
	}
	for(int i=1;i<=cnt;i++){
		for(edge v:loc[i]){
			if(!v.s){modify(v.l,v.w),modify(v.r+1,-v.w);}
			else ans[v.w]+=query(v.l);
		}
	}
	for(int i=1;i<=m;i++)cout<<ans[i]<<'\n';
	return 0;
}
                    
                
                
            
        
浙公网安备 33010602011771号