题意

题目链接

Sol

咕了一年的题解。。

并不算是很难,只是代码有点毒瘤

\(f[i][j]\)表示从\(i\)号节点出发走了\(2^j\)轮后总的距离

\(da[i][j]\)同理表示\(a\)的距离,\(db[i][j]\)与\(da\)同理

倍增优化一下

注意最后\(a\)可能还会走一次

#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP make_pair
#define fi first
#define se second
#define Fin(x) {freopen(#x".in","r",stdin);}
#define pb(x) push_back(x)
#define LL long long
//#define int long long
using namespace std;
const int MAXN = 1e5 + 10;
LL INF = 2e9 + 10, B = 20;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, jp[MAXN][21], nxa[MAXN], nxb[MAXN], flag[MAXN], h[MAXN];
LL f[MAXN][21], da[MAXN][21], db[MAXN][21];
struct Node {
LL Hi, id;
bool operator < (const Node &rhs) const{
return Hi == rhs.Hi ? h[id] < h[rhs.id] : Hi < rhs.Hi;
}
};
int get(int x, int y) {
return abs(h[x] - h[y]);
}
set<Node> s;
void Pre() {
s.insert((Node) {-INF * 2, 0}); s.insert((Node) {INF * 2, 0});
s.insert((Node) {-INF * 2 + 1, 0}); s.insert((Node) {INF * 2 + 1, 0});
s.insert((Node) {h[N], N});
memset(f, 0x3f, sizeof(f));
for(int i = N - 1; i >= 1; i--) {
set<Node> :: iterator y = s.lower_bound((Node) {h[i], i});
vector<Node> tmp; tmp.clear();
tmp.push_back((Node) {get(y -> id, i), y -> id}); y++;
tmp.push_back((Node) {get(y -> id, i), y -> id}); y--; y--;
tmp.push_back((Node) {get(y -> id, i), y -> id}); y--;
tmp.push_back((Node) {get(y -> id, i), y -> id});
sort(tmp.begin(), tmp.end());
nxa[i] = tmp[1].id;
nxb[i] = tmp[0].id;
s.insert((Node) {h[i], i});
if(tmp[1].id != 0 && tmp[0].id != 0) f[i][0] = tmp[1].Hi + db[tmp[1].id][0];
jp[i][0] = nxb[nxa[i]];
da[i][0] = get(i, nxa[i]);
db[i][0] = get(i, nxb[i]);
}
for(int j = 1; j <= B; j++)
for(int i = 1; i <= N; i++) {
if(jp[i][j - 1])
jp[i][j] = jp[jp[i][j - 1]][j - 1],
f[i][j] = f[i][j - 1] + f[jp[i][j - 1]][j - 1],
da[i][j] = f[i][j] == INF ? 0 : da[i][j - 1] + da[jp[i][j - 1]][j - 1];
} }
void print() {
for(int i = 1; i <= N; i++) printf("**%d\n", f[i][0]);
}
Pair Query(int pos, int val) {
LL a1 = 0, a2 = 0;
for(int i = B; ~i; i--)
if(f[pos][i] <= val)
val -= f[pos][i], a1 += da[pos][i], a2 += f[pos][i] - da[pos][i], pos = jp[pos][i];
if(da[pos][0] <= val) a1 += da[pos][0];
return MP(a1, a2);
}
signed main() {
// freopen("drive3.in", "r", stdin);
// freopen("a.out", "w", stdout);
N = read();
for(int i = 1; i <= N; i++) h[i] = read(); h[0] = INF; Pre();
// print();
int X0 = read(), ans = N;
double tmp = 1e22;
for(int i = 1; i <= N; i++) {
Pair now = Query(i, X0);
if(now.se == 0) continue;
if((double)now.fi / now.se < tmp) tmp = (double)now.fi / now.se, ans = i;
}
printf("%d\n", ans);
int M = read();
while(M--) {
int Si = read(), Mi = read();
Pair now = Query(Si, Mi);
printf("%d %d\n", now.fi, now.se);
}
return 0;
}

最新文章

  1. jquery实现多级下拉菜单
  2. fMRI: spatial smoothing
  3. zabbix 3.0.4 监控windows 服务
  4. Android Fragment完全解析,关于碎片你所需知道的一切
  5. struts2文件下载,动态设置资源地址
  6. sqlserver 获取时间年月日时分秒
  7. Android 动画的重复播放
  8. Python中的正斜杠与反斜杠
  9. 【转】关于Adapter的The content of the adapter has changed问题分析 关于Adapter的The content of the adapter has changed问题分析
  10. 使用ServletConfig获得web.xml资源中的参数
  11. 有引用外部jar包时(J2SE)生成jar文件
  12. ubuntu16.04之mongodb自动备份
  13. vuejs 1.x - 实例:搜索过滤
  14. (转)Spring Boot (十五): Spring Boot + Jpa + Thymeleaf 增删改查示例
  15. Android弹出窗口
  16. python 之 configparser 模块
  17. win10 HTTP 错误 500.21 - Internal Server Error
  18. GitHub上最火的74个Android开源项目(三)
  19. 10分钟轻松设置出 A+ 评分的 HTTP/2 网站
  20. LODOP打印控件之LODOP.NewPageA()方法

热门文章

  1. JavaScript DOM编程艺术 笔记(一)
  2. 转一个财务方面常用到的数字金额转成汉字大写金额 php类
  3. CSS: Multiple Attribute Selector [name=&quot;value&quot;][name2=&quot;value2&quot;]
  4. 128th LeetCode Weekly Contest Pairs of Songs With Total Durations Divisible by 60
  5. Linux and Shell 实用命令
  6. 利用JS获取本地时间和服务器时间
  7. lxml.html 中几种解析器的区别(转)
  8. 转 JSON在PHP中的基本应用
  9. 接口自动化测试框架 :APIAutoTest框架
  10. GPRS的短信和打电话功能