XX Open Cup, Grand Prix of Tokyo D,L
D
二分max值为L,判定能否使用的数构造出答案。
暂时不管L的限制。此时如果我们有一组解,表示为,其中是有多少个数在第位为。那么我们可以将减,加;或者减,加,构造出所有合法解。(为什么不是减,加呢?因为我们不仅要让不变,还要让不变,所以加减的数必然是偶数)
那么我们如何构造?设为异或和的第位,为和的第位。那么意味着为奇数,也就是,那么我们不妨将减去,此时每个数都出现了偶数次,那么我们将其除以二,我们设这样操作后的数为(),第位为。不难构造出。
L
我们对第一个限制分治,也就是,我们对坐标从小到大排序,每次分成左右两个区间,并且记录出现在左侧的红点和出现在右侧的蓝点,那么我们就想让红点和蓝点匹配。
直接暴力匹配是的(当然也体现不出分治的意义),但是这里有一个结论:最大权值的匹配必然是有一个颜色的点的权值最大。也就是,只能是左侧红点中最大的和右侧所有蓝点匹配;或者右侧蓝点最大的和左侧红点匹配。
证明很简单——假设当前我们的询问为,当前分治的区间为,左半部分为,右半部分为。若,那么区间内所有点对都满足条件。否则若,则左侧最大值和右侧最大值会落到这四个区间的两个中,那么根据抽屉原理,我们取和段时,必然会出现包含左侧最大值或右侧最大值的段。否则就是相交的情况,其实就是将四段变成三段或更少,也是满足条件的。
那么这样点对数就降到。我们处理出这些点对。回答询问可以让询问离线,将询问和点对按左节点从小往大\从大往小排序,用BIT处理前缀和后缀max即可。具体实现看程序。(有点像扫描线,但这里空间有些大,开线段树很危险,只能用树状数组了)
#include<bits/stdc++.h>
#define debug(...) std::cerr<<#__VA_ARGS__<<" : "<<__VA_ARGS__<<std::endl
const int maxn=200000,maxq=500005,N=maxn*20+maxq+maxq;
int n,q;
int x[maxn],y[maxn],w[maxn],clr[maxn],id[maxq],ql[maxq],qr[maxq],ans[maxq];
std::vector<int> tmp;
std::vector<std::array<int,3>> points;
std::vector<std::array<int,3>> query;
void divide(int l,int r) {
if(l==r) return;
int mid=l+r>>1,mx,rc;
divide(l,mid); divide(mid+1,r);
mx=-1;
for(int i=l;i<=mid;i++) {
if(mx<w[id[i]]&&clr[id[i]]==1) {
rc=i;
mx=w[id[i]];
}
}
if(mx!=-1) {
for(int i=mid+1;i<=r;i++) {
if(clr[id[i]]==1) continue;
int sx=x[id[rc]],tx=x[id[i]],W=w[id[rc]]+w[id[i]];
if(sx>tx) std::swap(sx,tx);
points.push_back({sx,tx,W});
}
}
mx=-1;
for(int i=mid+1;i<=r;i++) {
if(mx<w[id[i]]&&clr[id[i]]==2) {
rc=i;
mx=w[id[i]];
}
}
if(mx!=-1) {
for(int i=l;i<=mid;i++) {
if(clr[id[i]]==2) continue;
int sx=x[id[rc]],tx=x[id[i]],W=w[id[rc]]+w[id[i]];
if(sx>tx) std::swap(sx,tx);
points.push_back({sx,tx,W});
}
}
}
#define lowbit(x) (x&-x)
struct tree1 {
int val[N];
tree1 () {
memset(val,-1,sizeof val);
}
void add(int pos,int num) {
for(int i=pos;i<N;i+=lowbit(i)) {
val[i]=std::max(val[i],num);
}
}
int qry(int pos) {
int ret=-1;
for(int i=pos;i;i-=lowbit(i)) {
ret=std::max(ret,val[i]);
}
return ret;
}
}BIT1;
struct tree2 {
int val[N];
tree2 () {
memset(val,-1,sizeof val);
}
void add(int pos,int num) {
for(int i=pos;i;i-=lowbit(i)) {
val[i]=std::max(val[i],num);
}
}
int qry(int pos) {
int ret=-1;
for(int i=pos;i<N;i+=lowbit(i)) {
ret=std::max(ret,val[i]);
}
return ret;
}
}BIT2;
bool cmp1(int id1,int id2) {
return y[id1]<y[id2];
}
bool cmp2(int id1,int id2) {
return ql[id1]>ql[id2];
}
bool cmp3(std::array<int,3> t1,std::array<int,3> t2) {
return t1[0]>t2[0];
}
int number(int nj) {
return std::lower_bound(tmp.begin(),tmp.end(),nj)-tmp.begin()+1;
}
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++) {
scanf("%d%d%d",&x[i],&y[i],&w[i]);
clr[i]=1;
id[i]=i;
}
for(int i=n+1;i<=n+n;i++) {
scanf("%d%d%d",&x[i],&y[i],&w[i]);
clr[i]=2;
id[i]=i;
}
std::sort(id+1,id+n+n+1,cmp1);
divide(1,n+n);
for(auto par : points) tmp.push_back(par[0]),tmp.push_back(par[1]);
scanf("%d",&q);
for(int i=1;i<=q;i++) {
scanf("%d%d",&ql[i],&qr[i]);
tmp.push_back(ql[i]); tmp.push_back(qr[i]);
id[i]=i;
}
std::sort(tmp.begin(),tmp.end());
tmp.erase(std::unique(tmp.begin(),tmp.end()),tmp.end());
for(auto &par : points) par[0]=number(par[0]),par[1]=number(par[1]);
for(int i=1;i<=q;i++) ql[i]=number(ql[i]),qr[i]=number(qr[i]);
memset(ans,-1,sizeof ans);
////////////////////////////
std::sort(id+1,id+q+1,cmp2);
std::sort(points.begin(),points.end(),cmp3);
for(int i=1,j=0;i<=q;i++) {
while(j<(int)points.size()&&ql[id[i]]<points[j][0]) {
BIT1.add(points[j][1],points[j][2]);
j++;
}
ans[id[i]]=std::max(ans[id[i]],BIT1.qry(qr[id[i]]-1));
}
////////////////////////////
for(int i=q,j=(int)points.size()-1;i>=1;i--) {
while(j>=0&&ql[id[i]]>points[j][0]) {
BIT2.add(points[j][1],points[j][2]);
j--;
}
ans[id[i]]=std::max(ans[id[i]],BIT2.qry(qr[id[i]]+1));
}
////////////////////////////
for(int i=1;i<=q;i++) {
printf("%d\n",ans[i]);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!