首页 > 其他分享 >abc327F - Apples(线段树)

abc327F - Apples(线段树)

时间:2023-11-15 22:36:09浏览次数:40  
标签:abc327F puts int 线段 update 2e5 Apples include define

https://atcoder.jp/contests/abc327/tasks/abc327_f

我们将时间看作x轴,位置看作y轴,那么我们随着时间增加,维护新加的点对区间的贡献,同时减去过时的点,线段树区间加法维护最大值即可。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<set>
#include<queue>
#define A puts("YES")
#define B puts("NO")
//#define A puts("Yes")
//#define B puts("No")
#define fo(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (int (i)=(b);(i)>=(a);(i)--)
#define mk(x,y) make_pair((x),(y))
#define lc (o<<1)
#define rc (o<<1|1)
using namespace std;
//typedef __int128 i128;
typedef double db;
typedef long long ll;
const ll mo=1e9+7;
const ll inf=1ll<<60;
const int N=4e5+5;
int n,d,w,x,y,z,ans;
int t,a[N*4],mx[N*4];
vector<int> v[N];
void update(int o,int l,int r){
	if (x<=l && r<=y) {
		a[o]+=z;
		mx[o]+=z;
		return;
	}
	int m=(l+r)>>1;
	if (x<=m) update(lc,l,m);
	if (m<y) update(rc,m+1,r);
	
	mx[o]=max(mx[lc],mx[rc])+a[o];
}
void query(int o,int l,int r,int add){
	if (x<=l && r<=y) {
		ans=max(ans, mx[o]+add);
		return;
	}
	int m=(l+r)>>1;
	if (x<=m) query(lc,l,m,add+a[o]);
	if (m<y) query(rc,m+1,r,add+a[o]);
}
int main()
{
//	freopen("data.in","r",stdin);
//	freopen("ans.out","w",stdout);

	scanf("%d %d %d",&n,&d,&w);
	fo(i,1,n) {
		scanf("%d %d",&t,&x);
		v[t].emplace_back(x);
	}
	
	fo(i,1,2e5) {
		int st=i-d;
		if (st>0) {
			for (auto j:v[st]) {
				x=max(1,j-w+1); y=j; z=-1;
				update(1,1,2e5);
			}
		}
		
		for (auto j:v[i]) {
			x=max(1,j-w+1); y=j; z=1;
			update(1,1,2e5);
		}
		
		x=1; y=2e5;
		query(1,1,2e5,0);
	}
	
	printf("%d",ans);
	


	return 0;
} 

  

标签:abc327F,puts,int,线段,update,2e5,Apples,include,define
From: https://www.cnblogs.com/ganking/p/17834991.html

相关文章

  • 线段树
    线段树引入遇到过好多次线段树的题目,要么就是用其他的方法去解决,要么就是不会写!!今天痛定思痛,决定好好归纳整理一下线段树线段树解决的是「区间和」的问题,且该「区间」会被修改什么意思呢?举个简单的例子,对于nums=[1,2,3,4,5]如果我们需要多次求某些区间的和,是不是首先想......
  • 理解线段树和主席树:解决区间操作的利器
    在计算机科学和算法领域,区间操作问题是一类常见且重要的问题,它们涉及到在一维数据结构中执行查询和更新操作。线段树和主席树是两种用于解决这类问题的强大数据结构。本文将介绍这两种树状数据结构,以及它们在不同应用领域中的使用。什么是线段树?线段树是一种用于处理区间操作问......
  • 线段树历史值
    P6242【模板】线段树3支持区间加,区间取\(\min\),区间求和,区间\(\max\),区间历史\(\max\)。先提一嘴吉司机。就是对线段树的每个节点记录最大值,严格次大值和最大值个数,只在\(se<v<mx\)的区间操作,否则向下递归。如果没有区间加,复杂度势能分析是\(O((n+m)\logn)\)的,否则为......
  • 原点到线段的垂足
    原理:1) 求出向量ao在ab上的投影距离2)a沿着ab方向移动投影距离就是垂足点的位置 //获得原点到直线ab的垂点publicstaticVector2GetPerpendicularToOrigin(Vector2a,Vector2b){varab=b-a;varao=Vector2.zero-a;floatproj=Vector2.D......
  • 向量叉乘判断两点是否在线段同侧
    ap1×ab与ap2×ab的结果异号,则表示两点在线段两侧;同号则表示在线段同侧 有一个点在线段上或两个点都在线段上,当做在线段同侧处理 //两点是否在线段同侧publicstaticboolIsTwoPointSameSideOfSegment(Vector2a,Vector2b,Vector2p1,Vector2p2){vara_p1=......
  • 用线段树来接树状数组类的问题
    大致解决的问题就是区间查询以及单点的修改#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintN=5e5+10;inta[N],tag[N<<2];struct{ struct{ intl,r,sum; }tr[N<<2]; voidpush_up(inti){ tr[i].sum=tr[i<<1].sum+tr[i<......
  • 向量点乘判断点是否在线段上
    几种要考虑的情况1)点p和线段断点a,b重叠,pa•ab=pa.x*pa.y+ab.x*ab.y=02) pa,pb共线,则pa×pb=02-1)p在线段ab上,此时pa,pb的夹角为180度,cos(180)=-1,pa•ab=-|pa|*|ab|2-2)p在线段ab外,此时pa,pb的夹角为0度,cos(0)=1,pa•ab=|pa|*|ab|4)pa,pb不共线,cos(钝角)<0,cos(......
  • 点到线段的距离2
    几种要考虑的情况1)点和线段两端重叠的情况2)点在线段两侧的情况  p在另一侧的情况以此类推3)点在线段中间的情况   //点到线段的距离publicstaticfloatPointToSegmentDistance2(Vector2p,Vector2a,Vector2b){//点和线段端点重合varap=p......
  • 树状数组用线段树来写
    #include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintN=5e5+10;inta[N],tag[N<<2];struct{ struct{ intl,r,sum; }tr[N<<2]; voidpush_up(inti){ tr[i].sum=tr[i<<1].sum+tr[i<<1|1].sum; } voidbuild(inti......
  • F. Unique Occurrences(线段树分治+可撤销并查集)
    F.UniqueOccurrences假如我们删除所有权值为x的边,那么所有权值为x的边对答案的贡献就是\(\sumsz[u]*sz[v]\)sz表示两个联通块的大小,且(u,v)的边权为x我们可以用可撤销并查集来进行处理,简单来说就是将一条边的存在时间看作区间,然后挂到线段树上,然后遍历到每个叶子的时候进行......