题目描述

A国的城市可以看做是数轴上的整数点,有n辆卡车在公路上往返行驶,它们只能在到达某个城市才能掉头,掉头是不需要时间的,而且卡车在途中不能停下来。这n辆卡车初始时可能位于不同的城市,在某个时刻它们同时出发,每辆卡车每分钟可以到达下一个城市,即每分钟可以行使单位1的路程。当卡车到达终点时,它将会进入时空隧道,瞬间消失。给出每辆卡车的行驶的路径,即卡车的起点、中途每次掉头的点及终点,有m次查询,每次查询指定两辆卡车,问它们一共相遇多少次?
注意:卡车相遇点不一定是城市。另外,相遇时其中一辆卡车进入时光隧道不算相遇;起始瞬间两辆卡车位于同一地点不算相遇;其中一辆卡车正好掉头不算相遇。
n<=100000,m<100000,城市的编号在[1,10^9]之间。每辆卡车路径掉头的次数不超过3*10^5;所有卡车掉头的总次数之和不超过3*10^5.

输入:

第一行两个整数n,m,表示卡车的数量和查询的次数。
接下来n行,每行的第一个数为Ki(2<=Ki<=3*10^5),表示卡车的路径包含Ki个点,接下来有Ki个数,每个数在区间[1,10^9]之间,按顺序表示卡车行驶时经过的城市,包括起点和终点。
所有Ki之和超过3*10^5
接下来m行,每行两个整数,表示查询这两辆卡车一共相遇多少次。

输出:

对每次查询,输出一个整数,表示它们相遇次数。
50%的数据,n<100,Ki<1000,m<1000

思路:

首先我们应该将每一辆车的转折点按照发生时间来排序。讲每一个查询都保存下来,当然重复的我们只留一个去计算,其余的我们应当保存在一个与保留的那一个有关的数据结构里。顺便提一下,做这道题是一定要估计好空间复杂度,防止被卡空间。然后在保存一个询问的时候只保存在拐点少的那个的名下。然后枚举每一个拐点就可以了。
然后我们分析时间复杂度:
如果某个卡车的转折点小于k√个,即使和它名下存的查询关系多于k√个,但是它在转折点数组中的出现次数一定小于k√次。
如果某个卡车的转折点多于k√个,即使它在转折点一定枚举k√+次,但是和它有查询关系的卡车一定小于k√个。
通过以上分析,我们知道均摊的时间复杂度不会超过k√个。所以总的时间复杂度就是O(k32).

代码:(用hash表实现去重以及保存询问)

#include<algorithm>
#include<map>
#include<cstdio>
#include<vector>
#define LL long long
#define PII pair<int, int>
const int MAXN = 300010;
using namespace std;
struct event {int id, p, dir; //id->trucks' number; p->position; dir->directionLL time;bool operator < (const event &rhs) const{if(time != rhs.time) return time < rhs.time;return dir > rhs.dir;}event(){}event(int a, int b, int c, LL d){id = a, p = b, dir = c; time = d;}
};
int h[2000000];
PII hsh[2000000];
int hshit(PII t)
{int p = 1LL * (t.second - t.first) * t.first * 12580 % 2000000;while(h[p] && hsh[p] != t) p = (p + 1) % 2000000;++ h[p];hsh[p] = t;return p;
}
struct query {int id, was_left, qid;query() {}query(int a, int b, int c) { id = a; was_left = b; qid = c; }
};
struct List {int id, num;vector<int> index;List *next;List(){next = NULL; id = num = -1;}
}*Adj[MAXN], *hs[2000000];
struct truck
{int k, p, dir;LL time;vector<query> queries;
} trucks[MAXN];
inline void GET(int &n)
{n = 0; char c;do c = getchar(); while(c > '9' || c < '0');while(c >= '0' && c <= '9') {n = n*10 + c - '0'; c = getchar();}
}
int n, m;
void init(event &e)
{trucks[e.id].p = e.p;trucks[e.id].dir = e.dir;trucks[e.id].time = e.time;
}
int check(const truck &a, const truck &b, LL pretime, int predir)
{if (!b.dir && pretime >= b.time)return 0;int b_pos, a_pos;if (!b.dir){b_pos = b.p;a_pos = (a.time - b.time) *(-predir) + a.p;}else{a_pos = a.p;b_pos = (a.time - b.time) * b.dir + b.p;}return b_pos < a_pos ? -1 : 1;
}
int ans[MAXN];
void solve(const truck &t, query &q, LL pretime, int predir)
{int is_left = check(t, trucks[q.id], pretime, predir);ans[q.qid] += (q.was_left * is_left == -1);q.was_left = is_left;
}
int main()
{vector<event> events;GET(n); GET(m);int x, newx;LL tsum;event e;for(int i = 0; i < n; ++ i){tsum = 0;GET(trucks[i].k); GET(x);for(int j = 0; j < trucks[i].k - 1; ++ j){GET(newx);e = event(i, x, x < newx ? 1 : -1, tsum);if(!j) init(e);else events.push_back(e);tsum += abs(x - newx);x = newx;}e = event(i, x, 0, tsum);events.push_back(e);}int a, b;for(int i = 0; i < m; i ++){GET(a); GET(b);-- a; -- b;if(a > b) swap(a, b);int t = hshit(PII(a, b));if(h[t] > 1) {hs[t]->num ++;hs[t]->index.push_back(i);continue;}else {if(!Adj[a]) {Adj[a] = new List();Adj[a]->num = 1;Adj[a]->id = b;hs[t] = Adj[a];hs[t]->index.push_back(i);}else {List *p = new List();p->next = Adj[a]->next;p->id = b;p->num = 1;Adj[a]->next = p;hs[t] = p;hs[t]->index.push_back(i);}}if (trucks[a].k > trucks[b].k) swap(a, b);trucks[a].queries.push_back(query(b, trucks[b].p < trucks[a].p ? -1 : 1, i));}sort(events.begin(), events.end());for(int i = 0; i < events.size(); i ++){e = events[i];LL prev_time = trucks[e.id].time;int prev_dir = trucks[e.id].dir;init(e);for(int i = 0; i < trucks[e.id].queries.size(); i ++){query &q = trucks[e.id].queries[i];solve(trucks[e.id], q, prev_time, prev_dir);}}int sz;for(int i = 0; i < n; i ++)for(List *p = Adj[i]; p; p = p->next) {sz = p->index.size();for(int j = 1; j < sz; j ++)ans[p->index[j]] = ans[p->index[0]];}for(int i = 0; i < m; ++i)printf("%d\n", ans[i]);return 0;
}

转载于:https://www.cnblogs.com/geng4512/p/5296911.html

COCI CONTEST #3 29.11.2014 KAMIONI相关推荐

  1. 2016 ACM / ICPC Asia dalian Regional Contest 题解(11 / 11)【每日亿题2021 / 2 / 17】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A .(2017 ACM ICPC dalian H)To begin or not to be ...

  2. linux+scp+失败_Linux scp 命令卡住的原因

    帆软报表FineReport中数据连接的JDBC连接池属性问题 连接池原理 在帆软报表FineReport中,连接池主要由三部分组成:连接池的建立.连接池中连接使用的治理.连接池的关闭.下面就着重讨论 ...

  3. oracle10.2 迁移,实战:Oracle10.2.0.4异机迁移并升级到Oracle 11.2.0.4

    环境: 源库:192.168.8.132  Oracle10.2.0.4 目标库:192.168.8.133 oracle11.2.0.4 OS:linux 5.4-64位 将原10G的库迁移到新主机 ...

  4. L84.linux命令每日一练 -- 第11章 Linux系统管理命令 -- rpm和yum

    11.19 rpm:RPM包管理器 11.19.1 命令详解 ​ [命令星级] ★★★★★ ​ [功能说明] ​ rpm命令的全称是Red Hat Package Manager(Red Hat包管理 ...

  5. 精通 Pandas:6~11

    原文:Mastering Pandas 协议:CC BY-NC-SA 4.0 译者:飞龙 六.处理缺失数据,时间序列和 Matplotlib 绘图 在本章中,我们将介绍一些必要的主题,这些主题对于培养 ...

  6. 这家消金公司增资至29亿(起底中国31家消金公司)

    目录 前序 全国消金公司盘点 消金公司发展路径浅析 消金公司经营业绩盘点 消金公司业务前景分析 后续 01 # 序言 序言 根据宁波银保监2023年4月23日发布的批复文件,同意浙江宁银消费金融股份有 ...

  7. 2014年全年考试计划

    考试名称 考试时间 ○公务员公共科目笔试 ○ 中央机关及其直属机构录用公务员公共科目笔试 2013年11月24日 北京市各级机关2014年考试录用公务员公共科目笔试 2013年12月8日  ○ 职称外 ...

  8. 2015 Multi-University Training Contest 5

    1001 MZL's Circle Zhou 1002 MZL's xor 水题中最后一个做的.因为看成i<j了. 后来听学长说才发现i可以等于j.真是orz. 1 # include < ...

  9. Oracle编程入门经典 第11章 过程、函数和程序包

    目录 11.1          优势和利益... 1 11.2          过程... 1 11.2.1       语法... 2 11.2.2       建立或者替换... 2 11.2 ...

最新文章

  1. webp-imageio 如何编译及使用
  2. C语言中size_t的陷阱
  3. PHP 2014.5.21的总结:
  4. Netty 基本介绍与核心组件(EventLoop、ChannelPipeline、ChannelHandler)
  5. 十年,从网管到首席架构师,我的成长感悟
  6. 网页视频地址批量抓取工具(原创)
  7. 知乎周刊之程序人生概要
  8. 计算机科学与技术基础与核心,浅谈计算机科学与技术专业核心课程教学
  9. 高德地图驾车导航使用
  10. 海思vo 分屏显示总结
  11. Powershell操作Excel简析
  12. TCP套接口的FIN_WAIT_2状态超时
  13. 《仗剑啸江湖》技术支持
  14. 电子产品PCB电路板散热的方法
  15. HTML做一个简单漂亮的旅游网页(纯html代码)重庆旅游 7页
  16. kubernetes开发环境的比较
  17. 关于眼镜保护的几点做法
  18. Jama实现奇异值分解需要注意的问题(SVD)
  19. 启用FM模块后VA01创建销售订单报错,消息号 FI311 “未在项目00001 11AA 中输入承诺项目”
  20. mathtype获得试用

热门文章

  1. USACO翻译:USACO 2014 FEB SILVER 三题
  2. 接口自动化测试系列(一):HTTP状态码
  3. 操作系统页面置换算法
  4. configParser模块详谈
  5. postMan下使用xdebug
  6. js动态获取时间的方式
  7. Bootstrap学习之二:栅格化布局
  8. 如何应对云爆发架构?四种方法替你解忧
  9. VC++ 19 (VS2015) 编译器系统环境变量配置
  10. Java基础知识强化83:System类之gc()方法(垃圾回收)以及和finalize()区别