当前位置: 首页 > news >正文

Google wave 的技术分析- Google 企业应用的桥头堡(Web . in Ente

谢琴律椿题目描述

小 D 正在研究交换。

小 D 认为一个整数序列是好的,当且仅当它先(不严格)上升,后(不严格)下降。

形式化地,我们认为序列

是好的,当且仅当存在某个

,使得对于任意

,有

,且对于任意

,有

小 D 得到了一个长度为 ?? 的序列

,他想让这个序列变成好的。

小 D 每次可以交换相邻的两个元素。因为交换很累,所以小 D 想知道,他最少需要交换多少次。

这下小 D 不会了,请你帮帮他。

subtask1(15pts):

subtask2(20pts):

subtask3(15pts):

subtask4(15pts):

subtask5(20pts):

是一个

的排列。

subtask6(15pts):无特殊限制。

对于 100% 的数据,

方法

考虑贪心。

对于一个序列,如果我们要让他变好,其最小值一定会被移到最左边或最右边。移到最左边或最右边就取决于移到哪边需要的次数最少。

于是,我们再考虑分治。每次将对序列中最小的数移到最边上,给

加上移动次数,并将这个数删掉。这样,我们就又得到了一个序列。对序列进行这样的重复操作,直到

个数全部被删除,输出

即可。

但是,当我们有很多个并列最小的数时,对这些数删除的顺序是有讲究的。每次只能删除最左边或最右边的数,否则一定会产生两个相等的数交换位置的情况。这无疑是无意义的,会使答案不是最优。并且,应删除最左边或最右边中删除所需次数更少的一边。这样,才能保证后面被删除的数是最优的。

时间复杂度:

优化

观察到

最大能达到

是肯定卡不过去的。这时候我们便需要优化。

我们可以使用平衡树

。其实树状数组也可以用,又快又好些,吹普常数大的没边,但我是范浩强吹普死忠粉,我就要用。 维护

对一个序列分成三段,一段为要删的数前的数,一段为其自己,一段为其后面的数,启动次数就是前面的数的

和后面的数的

,然后再将前后的数合并,即将要删掉的数删掉。重复操作即可,细节看代码就行。我对我马蜂的美丽程度还是很自信的。

代码

#include

using namespace std;

#define int long long

#define usd unsigned

#define el cout << '\n'

#define lowbit(x) (x & (-x))

const int ranmod = 1e7;

#define random ((rand() * rand()) % ranmod)

#define AC return

#define AK return 0

#define YS cout << "YES"

#define NO cout << "NO"

#define Ys cout << "Yes"

#define No cout << "No"

#define ys cout << "yes"

#define no cout << "no"

#define ls(i) ch[i][0]

#define rs(i) ch[i][1]

#define debug(num) cerr << #num << ' ' << num << '\n'

// void init();

void main_();

signed main() {

ios :: sync_with_stdio(false);

cin.tie(NULL);

cout.tie(NULL);

// freopen(".in", "r", stdin);

// freopen(".out", "w", stdout);

int t = 1;

// cin >> t;

while(t--) {

// init();

main_();

}

AK;

}

const int mod = 95225987, maxn = 3 * 1e5 + 18;

int ch[maxn][2], rnd[maxn], val[maxn], siz[maxn], tot, rt;

int add(int num) {

tot++;

ls(tot) = rs(tot) = 0;

rnd[tot] = random;

siz[tot] = 1;

val[tot] = num;

return tot;

}

void push_up(int i) {

siz[i] = siz[ls(i)] + siz[rs(i)] + 1;

}

int merge(int l, int r) {

if(l * r == 0) return l + r;

int res = 0;

if(rnd[l] < rnd[r]) {

res = l;

rs(l) = merge(rs(l), r);

} else {

res = r;

ls(r) = merge(l, ls(r));

}

push_up(res);

return res;

}

void split(int rt, int v, int &l, int &r) {

if(rt == 0) {l = 0, r = 0; AC;}

if(val[rt] <= v) {

l = rt;

split(rs(l), v, rs(l), r);

push_up(l);

} else {

r = rt;

split(ls(r), v, l, ls(r));

push_up(r);

}

}

int show(int id) {

int a, b, mid;

split(rt, id, a, b);

split(a, id - 1, a, mid);

int res = min(siz[a], siz[b]);

debug(siz[a]), debug(siz[b]);

rt = merge(a, merge(mid, b));

return res;

}

int del(int id) {

int a, b, mid;

split(rt, id, a, b);

split(a, id - 1, a, mid);

int res = min(siz[a], siz[b]);

debug(siz[a]), debug(siz[b]);

rt = merge(a, b);

return res;

}

int n, ans = 0;

http://www.jsqmd.com/news/458017/

相关文章:

  • 人工智能与人类:未来写作的协同之路
  • 前端性能分析工具:dynaTrace Ajax Edition
  • 2026上海装修公司年轻人消费偏好调研报告:Z世代装修选择趋势 - 资讯焦点
  • Visual C# 新特性之dynamic类型
  • 比话降AI使用体验:知网AIGC检测专精工具值不值得买?
  • [原创]WCF技术剖析之十一:异步操作在WCF中的应用(上篇)
  • 2026 企业级 AI Agent 选型指南:从功能闭环到安全合规的深度架构拆解
  • 再互动解读雪花啤酒扫码领红包活动的“C端+B端”双轮驱动 - 品牌智鉴榜
  • 从零到一:Django Web 开发全流程实战(保姆级图文教程)
  • jQuery插件开发 - 其实很简单
  • Acrel-2000 电力监控系统 全维监控控配电 ATU 一键顺控实现无人值守
  • 每月加到1000元!这不只是养老金,是国家给咱老农民补发的“迟到工分”
  • 阶段三:CIPA 双流多模态模型 C++ TensorRT 边缘部署总结
  • EPLAN老司机教你玩转万能部件库
  • 警卫IT小白基础
  • iOS 上架 4.3a【一切源于机审】
  • 手轮跟随后台程序突然罢工?伺服电机原地抽搐?今天咱们就手把手盘一套200Smart PLC直连手轮的硬核解决方案,全程无尿点的实战经验直接甩脸上
  • COMSOL接触摩擦
  • 微信API接口的版本兼容处理:Java后端的多版本适配与平滑升级
  • 各系统安装openclaw具体步骤
  • 把B2B危机沟通做成一套可运行系统:四件套 + 72小时SOP
  • Linux线程(4)线程封装与线程互斥----mutex互斥量
  • C语言和python中写一个猜数字小游戏(菜鸟分享)
  • PCB常见问题:从设计到生产的避坑指南
  • firewalld 防火墙
  • 【深度解析】金属管转子流量计:核心原理、应用场景与实践落地 - 速递信息
  • 2026重庆酒店投资律所推荐|五家顶尖律所深度解析 - 界川
  • 2026年专业深度测评:正品溯源燕窝排名前五与前十名权威榜单
  • 2026年正品溯源燕窝专业深度测评:排名前五信誉品牌权威发布
  • 三电平ANPC型逆变器仿真模型:60度坐标系下的中点平衡控制与SVPWM控制策略研究