【出行计划 / 2】

9 篇文章 0 订阅

题目


在这里插入图片描述



思路

暴力 O ( m ⋅ n ) O(m \cdot n) O(mn)            \;\;\;\;\; 不可行

树状数组+差分 O ( m ⋅ l o g ( 5 e 5 ) ) O(m \cdot log(5e^{5})) O(mlog(5e5))            \;\;\;\;\; 可行

具体思路:

  1. t [ i ] ∈ [ q + k − c [ i ] + 1 ,    q + k ] t[i] \in [q+k-c[i]+1, \;q+k] t[i][q+kc[i]+1,q+k] 转换为 q + k ∈ [ t [ i ] − c [ i ] + 1 ,    t [ i ] ] q + k \in [t[i]-c[i]+1, \;t[i]] q+k[t[i]c[i]+1,t[i]]
  2. 为了使得范围不存在负数: q + k + 2 e 5 ∈ [ t [ i ] − c [ i ] + 1 + 2 e 5 ,    t [ i ] + 2 e 5 ] q+k+2e^{5}\in [t[i]-c[i]+1+2e^{5}, \;t[i]+2e^{5}] q+k+2e5[t[i]c[i]+1+2e5,t[i]+2e5]
  3. 预处理:对于每个出行计划,将映射到的范围的值通过 O ( 1 )    时间 O(1)\;时间 O(1)时间 的差分操作 + 1 +1 +1
  4. 区间求和:最后对于每次询问,直接用树状数组的 q u e r y 函数 query函数 query函数 O ( l o g n )    时间 O(logn)\;时间 O(logn)时间 求出该点处的实际值
  5. 确定树状数组大小: 存在操作 q u e r y ( q + k + 2 e 5 ) , M = 5 e 5 query(q + k + 2e^{5}), M = 5e^{5} query(q+k+2e5)M=5e5


TLE代码


#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int t[N], c[N];
int n, m, k;
int main()
{
    cin >> n >> m >> k;
    
    for(int i = 1; i <= n; i++) cin >> t[i] >> c[i];
    
    while (m -- ){
        int q;
        cin >> q;
        q += k;
        int cnt = 0;
        int l = q;
        for(int i = 1; i <= n; i++)
        {
            int r = l + c[i] - 1;
            if(t[i] >= l && t[i] <= r) cnt++;
        }
        
        cout << cnt << endl;
    }
    
    return 0;
}


正确代码


#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10, M = 5e5+10;
int t[N], c[N];
int n, m, k;
int b[M];
int lowbit(int x)
{
    return x & -x;
}
void update(int x, int d)
{
    for(; x < M; x += lowbit(x)) b[x] += d;
}
int query(int x)
{
    int retval = 0;
    for(; x; x -= lowbit(x)) retval += b[x];
    return retval;
}
void add(int l, int r, int d)
{
    update(l, d);
    update(r+1, -d);
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    
    cin >> n >> m >> k;
    
    for(int i = 1; i <= n; i++)
    {
        cin >> t[i] >> c[i];
        add(t[i]-k-c[i]+1+3e5, t[i]-k+3e5, 1);
    }

    while(m--)
    {
        int q;
        cin >> q;
        cout << query(q+3e5) << endl;
    }
    return 0;
}
  • 21
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,我无法确定您具体想了解什么关于CSP出行计划Java方面的内容。但是,我可以为您提供一些关于CSP出行计划和Java的基本信息。 CSP出行计划是一个基于云计算的智能交通出行服务平台,它可以为用户提供出行规划、路线推荐、实时路况、公交查询等服务。而Java是一种广泛使用的编程语言,它可以用于开发各种类型的应用程序,包括Web应用程序、桌面应用程序、移动应用程序等。 如果您想了解如何使用Java开发CSP出行计划相关的应用程序,您可以参考以下步骤: 1.了解CSP出行计划的API接口文档,确定需要使用哪些API接口。 2.使用Java编写代码,调用CSP出行计划的API接口,获取所需的数据。 3.根据获取的数据,进行相应的处理和展示,以实现所需的功能。 下面是一个使用Java调用CSP出行计划API接口获取公交查询结果的示例代码: ```java import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; public class BusQuery { public static void main(String[] args) { String appkey = "your_appkey";//你的appkey String city = "北京";//城市名 String bus = "特8";//公交线路名 String url = "http://api.csp.cn/bus/line?appkey=" + appkey + "&city=" + URLEncoder.encode(city) + "&bus=" + URLEncoder.encode(bus); String result = ""; try { URL realUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection(); conn.setRequestMethod("GET"); conn.connect(); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); String line; while ((line = in.readLine()) != null) { result += line; } in.close(); } catch (Exception e) { e.printStackTrace(); } System.out.println(result); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值