Q - Play With Sequence

HDU - 3971

这个题目是一个线段树,比较特别的线段树,就是c询问一定次数之后重新排序建树来优化减低复杂度。

第一次碰到这种题目有点迷。

这个题目写还是很好写的,就是重新排序建树的位置不太好找。

不过可以知道的是,这是更新花费时间和排序花费时间的一个平衡,这个是一个二次函数,这个二次函数的最低点可以自己测出来。

现在可能有点听不懂,写完代码就很好理解了,

我测的每隔2000次C的操作就重新建树排序是最优的。

800,1000,2200,3000 都是可以的。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
#include <map>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 3e5 + ;
typedef long long ll;
ll a[maxn], lc[maxn], rc[maxn], num[maxn];
string s[maxn];
struct node
{
ll lazy, max, min, len;
}tree[maxn*];
void push_up(int id)
{
tree[id].max = max(tree[id << ].max, tree[id << | ].max);
tree[id].min = min(tree[id << ].min, tree[id << | ].min);
//printf("tree[%d].min=%lld tree[%d].max=%lld\n", id, tree[id].min, id, tree[id].max);
} void build(int id,int l,int r)
{
tree[id].len = r - l + ;
tree[id].lazy = ;
if(l==r)
{
tree[id].max = tree[id].min = a[l];
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
push_up(id);
} void push_down(int id)
{
if(tree[id].lazy)
{
int val = tree[id].lazy;
tree[id << ].max += val;
tree[id << ].min += val;
tree[id << | ].max += val;
tree[id << | ].min += val;
tree[id << ].lazy += val;
tree[id << | ].lazy += val;
// printf("tree[%d].max=%lld tree[%d].min=%lld\n", id << 1, tree[id << 1].max, id << 1, tree[id << 1].min);
// printf("tree[%d].max=%lld tree[%d].min=%lld\n", id << 1 | 1, tree[id << 1 | 1].max, id << 1 | 1, tree[id << 1 | 1].min);
tree[id].lazy = ;
}
}
void update(int id,int l,int r,ll x,ll y,ll val)
{
push_down(id);
// printf("id=%d l=%d r=%d x=%lld y=%lld val=%lld\n", id, l, r, x, y, val);
if(tree[id].min>=x&&tree[id].max<=y)
{
tree[id].lazy = val;
tree[id].min += val;
tree[id].max += val;
//printf("id=%d min=%lld max=%lld\n", id, tree[id].min, tree[id].max);
return;
}
int mid = (l + r) >> ;
if (tree[id << ].max >= x && tree[id << ].min <= y) update(id << , l, mid, x, y, val);
if (tree[id << | ].max >= x && tree[id << | ].min <= y) update(id << | , mid + , r, x, y, val);
push_up(id);
} int query(int id,int l,int r,ll x,ll y)
{
push_down(id);
if(tree[id].max<=y&&tree[id].min>=x)
{
return tree[id].len;
}
int mid = (l + r) >> , ans = ;
if (tree[id << ].max >= x && tree[id << ].min <= y) ans += query(id << , l, mid, x, y);
if (tree[id << | ].max >= x && tree[id << | ].min <= y) ans += query(id << | , mid + , r, x, y);
return ans;
} void push_alldown(int id,int l,int r)
{
if(l==r)
{
a[l] = tree[id].max;
return;
}
push_down(id);
int mid = (l + r) >> ;
push_alldown(id << , l, mid);
push_alldown(id << | , mid + , r);
} int main()
{
int n, m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for (int i = ; i <= n; i++) scanf("%lld", &a[i]);
sort(a + , a + + n);
build(, , n);
int cnt = ;
for(int i=;i<=m;i++)
{
cin >> s[i];
if (s[i] == "C") scanf("%lld%lld%lld", &lc[i], &rc[i], &num[i]), cnt++;
else scanf("%lld%lld", &lc[i], &rc[i]), num[i] = ;
}
int tot = ;
for(int i=;i<=m;i++)
{
if(s[i]=="C")
{
++tot;
//push_alldown(1, 1, n);
//printf("lc[%d]=%lld rc[%d]=%lld num[%d]=%lld\n", i, lc[i], i, rc[i], i, num[i]);
update(, , n, lc[i], rc[i], num[i]);
if(tot%==)
{
push_alldown(, , n);
sort(a + , a + + n);
build(, , n);
}
}
else
{
int ans = query(, , n, lc[i], rc[i]);
printf("%d\n", ans);
}
}
}
}

线段树 排序建树

Q - Play With Sequence HDU - 3971 线段树 重新排序建树的更多相关文章

  1. hdu 3436 线段树 一顿操作

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  2. hdu 3397 线段树双标记

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  3. hdu 2871 线段树(各种操作)

    Memory Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  4. hdu 4267 线段树间隔更新

    A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  5. hdu 4747 线段树

    Mex Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  6. hdu 3954 线段树 (标记)

    Level up Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  7. hdu 1754 线段树(Max+单点修改)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  8. hdu 1166 线段树(sum+单点修改)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  9. hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

随机推荐

  1. BAT脚本编写要点_特殊字符

    BAT脚本编写要点(1)_特殊字符 分类: 其他 2011-03-20 00:58 5621人阅读 评论(0) 收藏 举报 脚本cdatecmdtreesystem 1. 点 与echo连用,作用是换 ...

  2. 数据结构和算法(Golang实现)(27)查找算法-二叉查找树

    二叉查找树 二叉查找树,又叫二叉排序树,二叉搜索树,是一种有特定规则的二叉树,定义如下: 它是一颗二叉树,或者是空树. 左子树所有节点的值都小于它的根节点,右子树所有节点的值都大于它的根节点. 左右子 ...

  3. undefined 和 not defined

    概念上的解释: undefined是javascript语言中定义的五个原始类中的一个,换句话说,undefined并不是程序报错,而是程序允许的一个值. not defined是javascript ...

  4. qad progress数据库启动出错解决

    1. 启动时报:SYSTEM ERROR: Wrong dbkey in block. Found 0, should be 6342528 in area 36.  (439) ** Save fi ...

  5. Sentry实时应用错误跟踪系统在Kubernetes中私有化部署

    应用错误跟踪系统:对软件系统运行过程中产生的错误日志进行收集从而实现监控告警. 虽然软件错误❌是不可避免的,但是可以降低错误数. 提高对错误的治理能力能让错误带来的损失降到最低 ​

  6. 腾讯云集群服务部署mysql并挂载到服务器

    一.背景 由于现在大部分的应用都是运行在云服务器上的,而现在大多数文章都是主要写如何在服务器上使用docker去运行mysql,比较少有介绍云服务器上的.再加上现在k8s比较火爆,而云厂商大多数都提供 ...

  7. 基于Python的Webservice开发(四)-泛微OA的SOAP接口

    一.功能需求 泛微e-cology可以在流程中调用Webservice接口实现与其他系统的联动等复杂功能.但是目前泛微文档中仅提供了调用的方法,但是没有关于接口的相关开发信息. 本次案例是用Pytho ...

  8. 详解 JDK8 新增的日期时间类

    JDK8 新增的日期时间类 在本人之前的博文<处理时间的类 -- System类.Date类 .SimpleDateFormat类 与 Calendar类>中,讲到过表示时间的类,有三类: ...

  9. 4. Object

    1. Object.is( );  //用来判断,不同等 == 与===接近.NaN作出的调整 let obj={a:1,b:2}; Object.is(obj,obj);//true Object. ...

  10. 高级数据结构---赫(哈)夫曼树及java代码实现

    我们经常会用到文件压缩,压缩之后文件会变小,便于传输,使用的时候又将其解压出来.为什么压缩之后会变小,而且压缩和解压也不会出错.赫夫曼编码和赫夫曼树了解一下. 赫夫曼树: 它是一种的叶子结点带有权重的 ...