HDU 6315.Naive Operations-线段树(两棵树合并)(区间单点更新、区间最值、区间求和)+思维 (2018 Multi-University Training Contest 2 1007)
6315.Naive Operations
题意很好理解,但是因为区间求和求的是向下取整的a[i]/b[i],所以直接分数更新区间是不对的,所以反过来直接当a[i]==b[i]的时候,线段树对应的位置更新+1操作是可取的,但是怎样才能在合适的时候+1操作呢?一开始智障想的是只要单点是b[i]的倍数就可以啊,但是这样就相当于单点查询的操作,铁定超时到上天,但是反过来就可以啊,直接一开始给一个数组赋值为b[i]的值,区间更新的时候所有的都更新,然后区间查询一下最小值,有0就说明有的已经正好减完b[i]个,然后tree数组进行+1操作就可以了,然后变为0的数组重新赋值相应的b[i]的值就可以了。因为b[i]是1-n的全排列,所以这种操作是可行的。然后我倒着思路写就过了,mdzz。。。
dls的思路也是这样的,贴一下dls的思路的题解:

代码:
//1007-6315-线段树-其实是两个线段树,合到一起
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
typedef long long ll;
using namespace std;
const int maxn=1e5+;
const int inf=0x3f3f3f3f;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 int tree[maxn<<],cnt[maxn<<],col[maxn<<],b[maxn],n,m;//tree建树求和,col延时标记,cnt暂时标记增加的数量 void pushup(int rt)
{
cnt[rt]=min(cnt[rt<<],cnt[rt<<|]);
tree[rt]=tree[rt<<]+tree[rt<<|];
} void pushdown(int rt)
{
if(col[rt]){
cnt[rt<<]-=col[rt];
cnt[rt<<|]-=col[rt];
col[rt<<]+=col[rt];
col[rt<<|]+=col[rt];
col[rt]=;
}
} void build(int l,int r,int rt)
{
if (l==r){
cnt[rt]=b[l];
tree[rt]=col[rt]=;
return;
} int m=(l+r)>>;
build(lson);
build(rson);
pushup(rt);
} void update(int L,int R,int temp,int l,int r,int rt)
{
if(temp==){
if(l==r){
cnt[rt]=b[l];
tree[rt]+=;
return ;
} pushdown(rt);
int m=(l+r)>>;
if (L<=m) update(L,R,cnt[rt<<]==,lson);
if (R> m) update(L,R,cnt[rt<<|]==,rson);
}
else{
if(L<=l&&r<=R){
cnt[rt]-=;
col[rt]+=;
return ;
} pushdown(rt);
int m=(l+r)>>;
if (L<=m) update(L,R,,lson);
if (R> m) update(L,R,,rson);
}
pushup(rt);
} int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R){
return tree[rt];
} pushdown(rt);
int m=(l+r)>>;
int ret=;
if(L<=m) ret+=query(L,R,lson);
if(R> m) ret+=query(L,R,rson);
return ret;
} int main()
{
while(~scanf("%d%d",&n,&m)){
memset(cnt,inf,sizeof(cnt));
memset(tree,,sizeof(tree));
memset(col,,sizeof(col));
for(int i=;i<=n;i++)
scanf("%d",&b[i]);
build(,n,);
char s[];int l,r;
for(int i=;i<m;i++){
scanf("%s%d%d",s,&l,&r);
if(s[]=='a'){
update(l,r,cnt[]==,,n,);
}
else{
printf("%d\n",query(l,r,,n,));
}
}
}
return ;
}
讲道理,这个题写的我已经没有脾气了,因为我敲的时候,手抖把int m=(l+r)>>1,敲成int m=(l+r)<<1了,然后找了一晚上+一上午的错,最后快要撞墙的的时候,瞄了一眼代码,然后,就发现,哎哟我勒个去,我这个是不是写反了,mdzz,我去撞墙。。。
溜了。
HDU 6315.Naive Operations-线段树(两棵树合并)(区间单点更新、区间最值、区间求和)+思维 (2018 Multi-University Training Contest 2 1007)的更多相关文章
- HDU-DuoXiao第二场hdu 6315 Naive Operations 线段树
hdu 6315 题意:对于一个数列a,初始为0,每个a[ i ]对应一个b[i],只有在这个数字上加了b[i]次后,a[i]才会+1. 有q次操作,一种是个区间加1,一种是查询a的区间和. 思路:线 ...
- 杭电多校第二场 hdu 6315 Naive Operations 线段树变形
Naive Operations Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 502768/502768 K (Java/Other ...
- HDU 6315 Naive Operations(线段树区间整除区间)
Problem DescriptionIn a galaxy far, far away, there are two integer sequence a and b of length n.b i ...
- HDU - 6315 Naive Operations (线段树+思维) 2018 Multi-University Training Contest 2
题意:数量为N的序列a和b,a初始全为0,b为给定的1-N的排列.有两种操作:1.将a序列区间[L,R]中的数全部+1:2.查询区间[L,R]中的 ∑⌊ai/bi⌋(向下取整) 分析:对于一个位置i, ...
- HDU 6315 Naive Operations(线段树+复杂度均摊)
发现每次区间加只能加1,最多全局加\(n\)次,这样的话,最后的答案是调和级数为\(nlogn\),我们每当答案加1的时候就单点加,最多加\(nlogn\)次,复杂度可以得当保证. 然后问题就是怎么判 ...
- hdu 6315 Naive Operations (2018 Multi-University Training Contest 2 1007)
Naive Operations Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 502768/502768 K (Java/Other ...
- HDU 6315: Naive Operations
Naive Operations Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 502768/502768 K (Java/Other ...
- HDU 6315 Naive Operations(线段树+区间维护)多校题解
题意:a数组初始全为0,b数组题目给你,有两种操作: 思路:dls的思路很妙啊,我们可以将a初始化为b,加一操作改为减一,然后我们维护一个最小值,一旦最小值为0,说明至少有一个ai > bi,那 ...
- HDU 6315 Naive Operations 【势能线段树】
<题目链接> 题目大意: 给出两个序列,a序列全部初始化为0,b序列为输入值.然后有两种操作,add x y就是把a数组[x,y]区间内全部+1,query x y是查询[x,y]区间内∑ ...
随机推荐
- Dubbo 的 Helloworld
前提条件 安装好了 ZooKeeper 作为注册中心 服务端 <?xml version="1.0" encoding="UTF-8"?> < ...
- 【bzoj4627】[BeiJing2016]回转寿司 离散化+树状数组
题目描述 给出一个长度为n的序列,求所有元素的和在[L,R]范围内的连续子序列的个数. 输入 第一行包含三个整数N,L和R,分别表示寿司盘数,满意度的下限和上限. 第二行包含N个整数Ai,表示小Z对寿 ...
- IE6,7,8支持css圆角
我们知道Webkit内核的浏览器支持-webkit-border-radius: 10px;属性(10px是圆角半径),可以直接解析出圆角;Firefox浏览器支持-moz-border-radius ...
- Java23个设计模式的简明教程
设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于 ...
- Antlr 在 idea 中正确使用的方式
问题 Caused by: java.io.InvalidClassException: org.antlr.v4.runtime.atn.ATN; Could not deserialize ATN ...
- git使用笔记(四)远程操作
By francis_hao Nov 19,2016 以一张图说明远程操作,图片来自参考[2] git clone 从远端主机克隆一个版本库,若省略directory则生成一个和远端同名的版本库 ...
- [SDOI2016] 排列计数 (组合数学)
[SDOI2016]排列计数 题目描述 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰 ...
- 有关spring的各种下载资料的网站
spring的文件和jar包下载的网站: https://repo.spring.io/release/org/springframework/spring/ spring 各个版本源码下载的资料: ...
- linux 监控网卡实时流量iftop
一.安装iftop Centos也可以直接yum install iftop -y http://www.tcpdump.org/release/ 到如下获取libpcap.tcpdump iftop ...
- synchronized ---- 作用
获得同步锁: 1.清空工作内存: 2.从主内存拷贝对象副本到工作内存: 3.执行代码(计算或者输出等): 4.刷新主内存数据: 5.释放同步锁.