火神的鱼

2024-03-16 23:18
文章标签 火神

本文主要是介绍火神的鱼,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

火神的鱼

题解

挺水的一道题

由于d是恒大于0的,所以我们知道鱼的x值与y值应该是递增的。而只有一条鱼它x所加的区间在\[x1-x,x2-x\]y所加的区间在\[y1-y,y2-y\]时才有可能使得这条鱼在渔网中,我们考虑如何维护鱼所加的操作。

我们可以先根据鱼的下标建一棵线段树,用来存储当前区间被那些操作所影响到。由于这是一个线段树的形式,一个操作只能在log_{n}个不相交的区间中出现。我们从根节点走到任意一个叶节点所经过的节点的路径上所有的操作就是所有对这个节点有影响的操作,无论是询问还是移动。

但是这样的操作是没有顺序的,无法维护每个询问的答案。

我们考虑每一个节点对哪些询问产生了贡献,肯定只有处在将它加到在渔网中的区间的操作区间中的询问有贡献。我们可以线段树维护所有询问。它的每个位置记录当前操作节点对当前访问到的鱼区间产生贡献的大小。明显,如果当前区间不在操作节点的区间内,其贡献为0,否则就为它的操作值。

如果到达鱼区间的叶子节点的话,操作节点的线段树上有且仅有对其产生贡献的操作。我们只需要对符合条件的区间中,满足条件的询问加上这个点的贡献即可。符合条件的区间,可以在线段树上二分找到,至于当前询问符不符合条件,可以用懒标记来维护。

时间复杂度O\left(nlog^2_{n} \right )的样子。

源码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define MAXN 30005
typedef long long LL;
typedef unsigned long long uLL;
const int INF=0x7f7f7f7f;
typedef pair<int,int> pii;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
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;
}
int t,m,n,ans[MAXN],stak;
struct tree{LL x,y;int lzy,sum;bool ta;}tr[MAXN<<2];
struct query{int opt,id;LL d;};
vector<query>Ask[MAXN<<2];
struct point{LL x,y;}le,ri,f[MAXN];
void Insert(int rt,int l,int r,int al,int ar,query aw){if(l>r||l>ar||r<al)return ;int mid=l+r>>1;if(al<=l&&r<=ar){Ask[rt].push_back(aw);return ;}if(al<=mid)Insert(rt<<1,l,mid,al,ar,aw);if(ar>mid)Insert(rt<<1|1,mid+1,r,al,ar,aw);
}
void pushdown(int rt){if(tr[rt].lzy){tr[rt<<1].lzy+=tr[rt].lzy;tr[rt<<1|1].lzy+=tr[rt].lzy;if(tr[rt<<1].ta)tr[rt<<1].sum+=tr[rt].lzy;if(tr[rt<<1|1].ta)tr[rt<<1|1].sum+=tr[rt].lzy;tr[rt].lzy=0;}
}
void insertx(int rt,int l,int r,int ai,LL aw){if(l>r||l>ai||r<ai)return ;if(l==r){tr[rt].x=aw;return ;}int mid=l+r>>1;pushdown(rt);if(ai<=mid)insertx(rt<<1,l,mid,ai,aw);if(ai>mid)insertx(rt<<1|1,mid+1,r,ai,aw);tr[rt].x=tr[rt<<1].x+tr[rt<<1|1].x;
}
void inserty(int rt,int l,int r,int ai,LL aw){if(l>r||l>ai||r<ai)return ;if(l==r){tr[rt].y=aw;return ;}int mid=l+r>>1;pushdown(rt);if(ai<=mid)inserty(rt<<1,l,mid,ai,aw);if(ai>mid)inserty(rt<<1|1,mid+1,r,ai,aw);tr[rt].y=tr[rt<<1].y+tr[rt<<1|1].y;
}
void insertt(int rt,int l,int r,int ai,bool aw){if(l>r||l>ai||r<ai)return ;if(l==r){tr[rt].ta=aw;return ;}int mid=l+r>>1;pushdown(rt);if(ai<=mid)insertt(rt<<1,l,mid,ai,aw);if(ai>mid)insertt(rt<<1|1,mid+1,r,ai,aw);
}
int queryx(int rt,int l,int r,int k){if(l==r)return l;int mid=l+r>>1;pushdown(rt);if(tr[rt<<1].x>=k)return queryx(rt<<1,l,mid,k);return queryx(rt<<1|1,mid+1,r,k-tr[rt<<1].x);
}
int queryy(int rt,int l,int r,int k){if(l==r)return l;int mid=l+r>>1;pushdown(rt);//printf("queryy %d %d %d %d %d\n",l,r,k,tr[rt<<1].y,tr[rt<<1|1].y); if(tr[rt<<1].y>=k)return queryy(rt<<1,l,mid,k);return queryy(rt<<1|1,mid+1,r,k-tr[rt<<1].y);
}
void Putin(int rt){int siz=Ask[rt].size();for(int i=0;i<siz;i++){//printf("PutIn%d\n",Ask[rt][i].id);if(Ask[rt][i].opt==1)insertx(1,1,m,Ask[rt][i].id,Ask[rt][i].d);if(Ask[rt][i].opt==2)inserty(1,1,m,Ask[rt][i].id,Ask[rt][i].d);if(Ask[rt][i].opt==3)insertt(1,1,m,Ask[rt][i].id,1);}
}
void Putout(int rt){int siz=Ask[rt].size();for(int i=0;i<siz;i++){//printf("PutOut%d\n",Ask[rt][i].id);if(Ask[rt][i].opt==1)insertx(1,1,m,Ask[rt][i].id,0);if(Ask[rt][i].opt==2)inserty(1,1,m,Ask[rt][i].id,0);if(Ask[rt][i].opt==3)insertt(1,1,m,Ask[rt][i].id,0);}Ask[rt].clear();
}
void modify(int rt,int l,int r,int al,int ar,int aw){if(l>r||l>ar||r<al)return ;if(al<=l&&r<=ar){if(tr[rt].ta)tr[rt].sum+=aw;tr[rt].lzy+=aw;return ;}int mid=l+r>>1;pushdown(rt);if(al<=mid)modify(rt<<1,l,mid,al,ar,aw);if(ar>mid)modify(rt<<1|1,mid+1,r,al,ar,aw);
}
void Search(int rt,int l,int r){if(l>r)return ;//printf("toPUT %d %d\n",l,r);Putin(rt);if(l==r){int al=max(queryx(1,1,m,le.x-f[l].x),queryy(1,1,m,le.y-f[l].y));int ar=min(queryx(1,1,m,ri.x-f[l].x+1LL)-1,queryy(1,1,m,ri.y-f[l].y+1LL)-1);//printf("Search%d:%d %d\n",l,al,ar);if(al>ar){Putout(rt);return ;}//printf("%d add on %d %d %d\n",l,al,ar,ri.y-f[l].y+1LL);modify(1,1,m,al,ar,1);Putout(rt);return ;}int mid=l+r>>1;Search(rt<<1,l,mid);Search(rt<<1|1,mid+1,r);Putout(rt);
}
int getAns(int rt,int l,int r,int ai){if(l>r)return 0;if(l==r)return tr[rt].sum;int mid=l+r>>1;pushdown(rt);if(mid>=ai)return getAns(rt<<1,l,mid,ai);return getAns(rt<<1|1,mid+1,r,ai);
}
void build(int rt,int l,int r){tr[rt].sum=tr[rt].lzy=tr[rt].x=tr[rt].y=tr[rt].ta=0;if(l==r)return ;int mid=l+r>>1;build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);
}
signed main(){freopen("fish.in","r",stdin);freopen("fish.out","w",stdout);read(t);while(t--){read(n);read(le.x);read(le.y);read(ri.x);read(ri.y);for(int i=1;i<=n;i++)read(f[i].x),read(f[i].y);read(m);m++;build(1,1,m);stak=0;for(int i=1;i<m;i++){query x;int l,r;read(x.opt);x.id=i;read(l);read(r);if(x.opt!=3)read(x.d);Insert(1,1,n,l,r,x);if(x.opt==3)ans[++stak]=i;}insertx(1,1,m,m,INF);inserty(1,1,m,m,INF);Search(1,1,n);for(int i=1;i<=stak;i++)printf("%d\n",getAns(1,1,m,ans[i]));}return 0;
}

谢谢!!!

这篇关于火神的鱼的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/817057

相关文章

【易学】周易入门 ② ( 易学案例 | 推背图 | 火神山和雷神山 | 科学 与 玄学 的关系 | 科学 - “ 三维智慧 “ | 玄学 - “ 高维智慧 “ | 开悟 | 道与术 )

文章目录 一、易学案例1、推背图2、火神山和雷神山 二、科学 与 玄学1、科学 与 玄学 的关系2、科学 - " 三维智慧 "3、玄学 - " 高维智慧 "4、开悟 - " 打破认知 开启智慧 "5、道与术 一、易学案例 1、推背图 李世民 命 天文学家 李淳风 , 相士 袁天罡 推算大唐气运 , 李淳风 写了 一百多年 的 唐朝国运 , 袁天罡

武汉火神山医院紧急招募 IT 运维志愿者需求

为抗击新型冠状病毒感染的肺炎疫情,确保建设中的火神山医院信息系统正常运转,现面向全国 IT 企业公开招募院内 IT 运维志愿者。 委托 HIT 专家网发布具体需求如下: 一、工作地点:火神山医院(武汉市蔡甸区)。 二、工作内容:院内(含污染区)终端维护,包括电脑、打印机、终端网络等桌面运维工作。 三、报名条件:熟悉医院 IT 业务和桌面运维工作内容,勇于担当奉献的 IT 企业组织的志愿者队伍

【HDU5283】【JZOJ4694】火神的鱼

###Description 火神最爱的就是吃鱼了,所以某一天他来到了一个池塘边捕鱼。池塘可以看成一个二维的平面,而他的渔网可以看成一个与坐标轴平行的矩形。 池塘里的鱼不停地在水中游动,可以看成一些点。有的时候会有鱼游进渔网,有的时候也会有鱼游出渔网。所以火神不知道什么时候收网才可以抓住最多的鱼,现在他寻求你的帮助。 他对池塘里的每条鱼都给予了一个标号,分别从1到n标号,n表示池塘里鱼的总数。鱼的

【BestCoder Round #59 (div.1) B】【JZOJ4693】疯狂的火神

Description 火神为了检验zone的力量,他决定单挑n个人。 由于火神训练时间有限,最多只有t分钟,所以他可以选择一部分人来单挑,由于有丽子的帮助,他得到了每个人特定的价值,每个人的价值由一个三元组(a,b,c)组成,表示如果火神在第x分钟单挑这个人(x指单挑完这个人的时间),他就会得到a-b*x的经验值,并且他需要c分钟来打倒这个人。 现在火神想知道,他最多可以得到多少经验值,由