LEIJP开船(线段树)

题目大意:

给出n个数,m个操作;

若m==0,表示开炮,开炮后面还有5 个参数l,r,a,k,p表示leijp 向l 到r 段开炮,l 段开了a 炮,以后l + 1 到p 段分别开a+k,a+k+k,
a+k+k+k···炮, p+1 到r 段开a+(p-l-1)k、a+(p-l-2)k···炮

若m==1,后面有l,r 表示询问区域为等差数列的最大长度;


解题思路:

因为升降序改变,单个操作很麻烦,因此不能以单个点建树,而是要以后面的数与前面的数之间的区间作为叶子节点(表示后面的数与前面的数的差),这样的话区间【l,r】更新就只需要增加k;而且求等差数列变成了求最大的连续序列;

因此,要求最大连续数列就要维护lsum,rsum,sum(左右开端的最大连续长度,这个节点的最大连续长度),但仅仅是最大长度并不够,合并的时候虽然它是连续的但并不能保证它的差分相等也就是左右的值相等,因此还需要lc,rc,来表示线段树的左右的值(也就是差分);区间操作lazy操作就不做解释;

得出结论:搞这个题要维护lsum,rsum,sum,l,r,lazy,lc,rc;


代码:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
struct node
{
	int ls,rs,s;
	int lc,rc;
	int l,r,lazy;
}tree[100005<<2];

void build(int k,int l,int r)
{
	tree[k].l = l,tree[k].r = r;
	tree[k].ls = tree[k].rs = tree[k].s = r-l+1;
	if(l == r)return;
	int mid = (l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
//	printf("%d % d %d\n",k,l,r);
}

void pushdown(int k)
{
	tree[k<<1].lc += tree[k].lazy;
	tree[k<<1].rc += tree[k].lazy;
	tree[k<<1].lazy += tree[k].lazy;
	tree[k<<1|1].lc += tree[k].lazy;
	tree[k<<1|1].rc += tree[k].lazy;
	tree[k<<1|1].lazy += tree[k].lazy;
	tree[k].lazy = 0;
}

void pushup(int k)
{
	tree[k].lc = tree[k<<1].lc;
	tree[k].rc = tree[k<<1|1].rc;
	tree[k].ls = tree[k<<1].ls;
	tree[k].rs = tree[k<<1|1].rs;
	if(tree[k<<1].ls == tree[k<<1].r-tree[k<<1].l+1 && tree[k<<1].rc == tree[k<<1|1].lc)
	tree[k].ls += tree[k<<1|1].ls;
	//同一区间并且相等长度并且左右差分相等 
	if(tree[k<<1|1].rs == tree[k<<1|1].r-tree[k<<1|1].l+1 && tree[k<<1|1].lc == tree[k<<1].rc)
	tree[k].rs += tree[k<<1].rs;
	tree[k].s = max(tree[k<<1].s,tree[k<<1|1].s);
	if(tree[k<<1].rc == tree[k<<1|1].lc)
	tree[k].s = max(tree[k].s,tree[k<<1].rs+tree[k<<1|1].ls);
}

void updata(int k,int l,int r,int d)
{
	//printf("%d %d %d %d %d\n",k,tree[k].l,tree[k].r,l,r);
	if(tree[k].l == l && tree[k].r == r)
	{
		tree[k].lc += d;
		tree[k].rc += d;
		tree[k].lazy += d; 
		return;
	}
	if(tree[k].lazy != 0)pushdown(k);
	int mid = (tree[k].l+tree[k].r)>>1;
	if(l > mid)updata(k<<1|1,l,r,d);
	else if(r <= mid)updata(k<<1,l,r,d);
	else
	{
		updata(k<<1,l,mid,d);
		updata(k<<1|1,mid+1,r,d);
	}
	pushup(k);
}

int query(int k,int l,int r,int &lc,int &rc,int &ls,int &rs)
{
	if(tree[k].l == l && tree[k].r == r)
	{
		lc = tree[k].lc;
		rc = tree[k].rc;
		ls = tree[k].ls;
		rs = tree[k].rs;
		return tree[k].s;
	}
	if(tree[k].lazy != 0)pushdown(k);
	int mid = (tree[k].l + tree[k].r) >> 1;
	if(l > mid)return query(k<<1|1,l,r,lc,rc,ls,rs);
	else if(r <= mid)return query(k<<1,l,r,lc,rc,ls,rs);
	else 
	{
		int a,b,c,d;
		int A,B,C,D;
		int tempone = query(k<<1,l,mid,a,b,c,d);
		int temptwo = query(k<<1|1,mid+1,r,A,B,C,D);
		lc = a,rc = B,ls = c,rs = D;
		if(b == A && mid-l+1 == ls)ls += C;
		if(b == A && r - mid == rs)rs += d;
		int ans = max(tempone,temptwo);
		if(b == A)ans = max(ans,d+C);
		return ans;
	}
	pushup(k);
}

int main()
{
	freopen("wows.in","r",stdin);
	freopen("wows.out","w",stdout);
	int n,m,c,l,r,a,d,p,lc=0,rc=0,ls=0,rs=0;
	cin>>n>>m;
	build(1,1,n-1);//以点与点之间作为叶子节点 
	for(int i = 1;i <= m;i++)
	{
		scanf("%d",&c);
		if(c == 0)
		{
			scanf("%d%d%d%d%d",&l,&r,&a,&d,&p);
			if(p-1 >= l)updata(1,l,p-1,d);
			if(r-1 >= p)updata(1,p,r-1,-d);//更新区间内 
			if(l != 1)updata(1,l-1,l-1,a);
			if(r != n)updata(1,r,r,(l+r-2*p)*d-a); //更新相邻的点 
			//注意边界 
		}
		if(c == 1)
		{
			scanf("%d%d",&l,&r);
			if(l==r)printf("1\n");
			else printf("%d\n",query(1,l,r-1,lc,rc,ls,rs)+1);
		}
	}
	return 0;
}

刷题总结:

这是学长出的题,被坑了许久,不能被惯性思维束缚,仔细分析线段树到底维护什么,不能依照经验去维护点,然而这维护的是点与点之间的区间!!


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GeoPandas是一个开源的Python库,旨在简化地理空间数据的处理和分析。它结合了Pandas和Shapely的能力,为Python用户提供了一个强大而灵活的工具来处理地理空间数据。以下是关于GeoPandas的详细介绍: 一、GeoPandas的基本概念 1. 定义 GeoPandas是建立在Pandas和Shapely之上的一个Python库,用于处理和分析地理空间数据。 它扩展了Pandas的DataFrame和Series数据结构,允许在其中存储和操作地理空间几何图形。 2. 核心数据结构 GeoDataFrame:GeoPandas的核心数据结构,是Pandas DataFrame的扩展。它包含一个或多个列,其中至少一列是几何列(geometry column),用于存储地理空间几何图形(如点、线、多边形等)。 GeoSeries:GeoPandas中的另一个重要数据结构,类似于Pandas的Series,但用于存储几何图形序列。 二、GeoPandas的功能特性 1. 读取和写入多种地理空间数据格式 GeoPandas支持读取和写入多种常见的地理空间数据格式,包括Shapefile、GeoJSON、PostGIS、KML等。这使得用户可以轻松地从各种数据源中加载地理空间数据,并将处理后的数据保存为所需的格式。 2. 地理空间几何图形的创建、编辑和分析 GeoPandas允许用户创建、编辑和分析地理空间几何图形,包括点、线、多边形等。它提供了丰富的空间操作函数,如缓冲区分析、交集、并集、差集等,使得用户可以方便地进行地理空间数据分析。 3. 数据可视化 GeoPandas内置了数据可视化功能,可以绘制地理空间数据的地图。用户可以使用matplotlib等库来进一步定制地图的样式和布局。 4. 空间连接和空间索引 GeoPandas支持空间连接操作,可以将两个GeoDataFrame按照空间关系(如相交、包含等)进行连接。此外,它还支持空间索引,可以提高地理空间数据查询的效率。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值