dtoj#4212. 小X爱旅行(travel)

本文介绍了一种针对OIVillage铁路线路优化的算法,通过分块和凸包技巧,解决游客在限定区间内寻找最大美观度旅行路径的问题。算法处理大量数据修改和查询操作,适用于快速变化的旅游景点美观度评估。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

OIVillage 是一个风景秀美的乡村,为了更好的利用当地的旅游资源,吸引游客,推动经济发展,xkszltl 决定修建了一条铁路将当地 $n$ 个最著名的经典连接起来,让游客可以通过火车从铁路起点( $1$ 号景点)出发,依次游览每个景区。为了更好的评价这条铁路,xkszltl 为每一个景区都赋予了一个美观度,而一条旅行路径的价值就是它所经过的景区的美观度之和。不过,随着天气与季节的变化,某些景点的美观度也会发生变化。

xkszltl 希望为每位旅客提供最佳的旅行指导,但是由于游客的时间有限,不一定能游览全部景区,然而他们也不希望旅途过于短暂,所以每个游客都希望能在某一个区间内的车站结束旅程,而 xkszltl 的任务就是为他们选择一个终点使得旅行线路的价值最大。可是当地的景点与前来观光的旅客实在是太多了,xkszltl 无法及时完成任务,于是找到了准备虐杀 NOI2019 的你,希望你能帮助他完成这个艰巨的任务。

输入:

第一行给出一个整数 $n$,接下来一行给出 $n$ 的景区的初始美观度。

第三行给出一个整数 $m$,接下来 $m$ 行每行为一条指令:

$1.~~~0~x~y~k$:表示将 $x$ 到 $y$ 这段铁路边上的景区的美观度加上 $k$;

$2.~~~1~x~y$:表示有一名旅客想要在 $x$ 到 $y$ 这段(含 $x$ 与 $y$ )中的某一站下车,你需要告诉他最大的旅行价值。

数据范围:

对于 $20\%$ 的数据,$n,m≤3000$;

对于 $40\%$ 的数据,$n,m≤30000$;

对于 $50\%$ 的数据,$n,m≤50000$;

另外 $20\%$ 的数据,$n,m≤100000$,修改操作 $≤20$;

对于 $100\%$ 的数据,$n,m≤100000$。

算法标签:分块,凸包

思路:

考虑分块计算,对于每一个块做一个凸包,对于单词修改或询问如果遍布整个块,就对这个块记录一个 $k,b$ 表示整个块的数都要进行的操作。

因为是一次函数所以更改后最优答案一定在凸包上。

对于只修改或查询一个块内一部分点的情况,暴力操作。

以下代码:

#include<bits/stdc++.h>
#define il inline
#define db double
#define LL long long
#define _(d) while(d(isdigit(ch=getchar())))
using namespace std;
const int N=1e5+5,M=1505;
const LL inf=1e18;
vector<int> v[M];
int n,m,sz,gr[N],sta[N],top;
LL sum[N],k[N],b[N];
il int read(){
    int x,f=1;char ch;
    _(!)ch=='-'?f=-1:f;x=ch^48;
    _()x=(x<<1)+(x<<3)+(ch^48);
    return f*x;
}
il db getk(int x,int y){
    return (db)(sum[x]-sum[y])/(db)(x-y);
}
il void build(int x){
    int l=(x-1)*sz+1,r=min(x*sz,n);
    sta[top=1]=l;
    for(int i=l+1;i<=r;i++){
        while(top>1&&getk(sta[top],sta[top-1])<getk(sta[top-1],i))top--;
        sta[++top]=i;
    }
    v[x].resize(top+1);
    for(int i=1;i<=top;i++)v[x][i]=sta[i];
}
il LL cal(int x){
    return sum[x]+k[gr[x]]*x+b[gr[x]];
}
il LL query(int x){
    int l=1,r=v[x].size()-1;
    if(l>r)return cal(v[x][1]);
    while(l<r){
        int mid=(l+r)>>1;
        if(cal(v[x][mid])<cal(v[x][mid+1]))l=mid+1;
        else r=mid;
    }
    return cal(v[x][l]);
}
il void update(int x){
    int l=(x-1)*sz+1,r=min(x*sz,n);
    LL v=k[x]*l+b[x];
    for(int i=l;i<=r;i++)sum[i]+=v,v+=k[x];
    k[x]=b[x]=0;
}
int main()
{
    n=read();sz=sqrt(n/3);
    for(int i=1;i<=n;i++)sum[i]=sum[i-1]+read();
    for(int i=1;i<=n;i++)gr[i]=(i-1)/sz+1;
    for(int i=1;i<=gr[n];i++)build(i);
    m=read();
    while(m--){
        int op=read(),x=read(),y=read();
        if(op){
            LL ans=-inf;
            if(gr[x]^gr[y]){
                for(int i=x;i<=gr[x]*sz;i++)ans=max(ans,cal(i));
                for(int i=(gr[y]-1)*sz+1;i<=y;i++)ans=max(ans,cal(i));
                for(int i=gr[x]+1;i<gr[y];i++)ans=max(ans,query(i));
            }
            else{
                for(int i=x;i<=y;i++)ans=max(ans,cal(i));
            }
            printf("%lld\n",ans);
        }
        else{
            int c=read();
            if(gr[x]^gr[y]){
                LL val=0;
                for(int i=x;i<=gr[x]*sz;i++)val+=c,sum[i]+=val;
                val=1ll*((gr[y]-1)*sz-x+1)*c;
                for(int i=(gr[y]-1)*sz+1;i<=y;i++)val+=c,sum[i]+=val;
                for(int i=y+1;i<=min(gr[y]*sz,n);i++)sum[i]+=val;
                for(int i=gr[y]+1;i<=gr[n];i++)b[i]+=val;
                update(gr[x]);update(gr[y]);build(gr[x]);build(gr[y]);
                val=-1ll*c*(x-1);
                for(int i=gr[x]+1;i<gr[y];i++)k[i]+=c,b[i]+=val;
            }
            else{
                LL val=0;
                for(int i=x;i<=y;i++)val+=c,sum[i]+=val;
                for(int i=y+1;i<=min(gr[y]*sz,n);i++)sum[i]+=val;
                for(int i=gr[y]+1;i<=gr[n];i++)b[i]+=val;
                update(gr[x]);build(gr[x]);
            }
        }
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/Jessie-/p/10443119.html

### Pandas 文件格式读写操作教程 #### 1. CSV文件的读取与保存 Pandas 提供了 `read_csv` 方法用于从 CSV 文件中加载数据到 DataFrame 中。同样,也可以使用 `to_csv` 将 DataFrame 数据保存为 CSV 文件。 以下是具体的代码示例: ```python import pandas as pd # 读取CSV文件 df = pd.read_csv('file.csv') # 加载本地CSV文件 [^1] # 保存DataFrame为CSV文件 df.to_csv('output.csv', index=False) # 不保存行索引 [^1] ``` --- #### 2. JSON文件的读取与保存 对于JSON格式的数据,Pandas 支持通过 `read_json` 和 `to_json` 进行读取和存储。无论是本地文件还是远程 URL 都支持。 具体实现如下所示: ```python # 读取本地JSON文件 df = pd.read_json('data.json') # 自动解析为DataFrame对象 [^3] # 从URL读取JSON数据 url = 'https://example.com/data.json' df_url = pd.read_json(url) # 直接从网络地址获取数据 # 保存DataFrame为JSON文件 df.to_json('output.json', orient='records') ``` --- #### 3. Excel文件的读取与保存 针对Excel文件操作Pandas 使用 `read_excel` 来读取 `.xls` 或 `.xlsx` 格式的文件,并提供 `to_excel` 方法导出数据至 Excel 表格。 注意:需要安装额外依赖库 `openpyxl` 或 `xlrd` 才能正常运行这些功能。 ```python # 安装必要模块 (如果尚未安装) !pip install openpyxl xlrd # 读取Excel文件 df_excel = pd.read_excel('file.xlsx', sheet_name='Sheet1') # 导出DataFrame为Excel文件 df.to_excel('output.xlsx', sheet_name='Sheet1', index=False) ``` --- #### 4. SQL数据库的交互 当涉及关系型数据库时,Pandas 可借助 SQLAlchemy 库连接各种类型的数据库(如 SQLite, MySQL)。它允许直接查询并将结果作为 DataFrame 返回;或者反过来把现有 DataFrame 插入到指定表中。 下面是基于SQLite的一个例子: ```python from sqlalchemy import create_engine # 创建引擎实例 engine = create_engine('sqlite:///database.db') # 查询SQL语句并返回DataFrame query = "SELECT name, salary, department FROM employees" sql_df = pd.read_sql(query, engine) # 计算各部门平均工资 avg_salary_by_dept = sql_df.groupby('department')['salary'].mean() # 将DataFrame存回SQL表 avg_salary_by_dept.to_sql(name='average_salaries_per_department', con=engine, if_exists='replace', index=True) ``` 上述片段说明了如何执行基本SQL命令以及后续数据分析流程[^4]。 --- #### 5. 多层次索引(MultiIndex)的应用场景 除了常规单维度索引外,在某些复杂情况下可能需要用到多级索引结构。这时可以依靠 MultiIndex 构建更加灵活的数据模型。 例如定义一个多层列名体系: ```python arrays = [['A','A','B','B'], ['foo','bar','foo','bar']] tuples = list(zip(*arrays)) index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) df_multi_indexed = pd.DataFrame([[0,1,2,3], [4,5,6,7]], columns=index) print(df_multi_indexed) ``` 这段脚本演示了怎样构建一个具有双重分类标签的表格布局[^2]。 --- ### 总结 综上所述,Pandas 是一种强大而易用的数据处理工具包,适用于多种常见文件类型之间的相互转换及其高级特性应用开发之中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值