AC日记——线段树练习5 codevs 4927
有n个数和5种操作
add a b c:把区间[a,b]内的所有数都增加c
set a b c:把区间[a,b]内的所有数都设为c
sum a b:查询区间[a,b]的区间和
max a b:查询区间[a,b]的最大值
min a b:查询区间[a,b]的最小值
第一行两个整数n,m,第二行n个整数表示这n个数的初始值
接下来m行操作,同题目描述
对于所有的sum、max、min询问,一行输出一个答案
10 6
3 9 2 8 1 7 5 0 4 6
add 4 9 4
set 2 6 2
add 3 8 2
sum 2 10
max 1 7
min 3 6
49
11
4
10%:1<n,m<=10
30%:1<n,m<=10000
100%:1<n,m<=100000
保证中间结果在long long(C/C++)、int64(pascal)范围内
PS:由于数据6出错导致某些人只有90分,已于2016.5.13修正。
出题人在此对两位90分的用户表示诚挚的歉意
思路:
裸线段树;
轻松ac;
来,上代码:
#include <cstdio>
#include <iostream>
#include <algorithm> #define maxn 100001
#define LL long long using namespace std; struct TreeNodeType {
LL l,r,mid,dis,max_,min_,flag,flag_; bool if_;
};
struct TreeNodeType tree[maxn<<]; LL if_z,n,m; char Cget; inline void read_int(LL &now)
{
now=,if_z=,Cget=getchar();
while(Cget<''||Cget>'')
{
if(Cget=='-') if_z=-;
Cget=getchar();
}
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
Cget=getchar();
}
now*=if_z;
} inline void tree_up(LL now)
{
tree[now].dis=tree[now<<].dis+tree[now<<|].dis;
tree[now].max_=max(tree[now<<].max_,tree[now<<|].max_);
tree[now].min_=min(tree[now<<].min_,tree[now<<|].min_);
} inline void tree_down(LL now)
{
if(tree[now].l==tree[now].r) return ;
if(tree[now].if_)
{
tree[now<<].flag=,tree[now<<].flag_=tree[now].flag_;
tree[now<<].if_=true,tree[now<<].max_=tree[now].flag_;
tree[now<<].min_=tree[now].flag_;
tree[now<<].dis=(tree[now<<].r-tree[now<<].l+)*tree[now].flag_;
tree[now<<|].flag=,tree[now<<|].flag_=tree[now].flag_;
tree[now<<|].if_=true,tree[now<<|].max_=tree[now].flag_;
tree[now<<|].min_=tree[now].flag_;
tree[now<<|].dis=(tree[now<<|].r-tree[now<<|].l+)*tree[now].flag_;
}
else
{
if(tree[now<<].if_)
{
tree[now<<].max_+=tree[now].flag;
tree[now<<].min_+=tree[now].flag;
tree[now<<].flag_+=tree[now].flag;
tree[now<<].dis+=(tree[now<<].r-tree[now<<].l+)*tree[now].flag;
}
else
{
tree[now<<].max_+=tree[now].flag;
tree[now<<].min_+=tree[now].flag;
tree[now<<].flag+=tree[now].flag;
tree[now<<].dis+=(tree[now<<].r-tree[now<<].l+)*tree[now].flag;
}
if(tree[now<<|].if_)
{
tree[now<<|].max_+=tree[now].flag;
tree[now<<|].min_+=tree[now].flag;
tree[now<<|].flag_+=tree[now].flag;
tree[now<<|].dis+=(tree[now<<|].r-tree[now<<|].l+)*tree[now].flag;
}
else
{
tree[now<<|].max_+=tree[now].flag;
tree[now<<|].min_+=tree[now].flag;
tree[now<<|].flag+=tree[now].flag;
tree[now<<|].dis+=(tree[now<<|].r-tree[now<<|].l+)*tree[now].flag;
}
}
tree[now].flag=,tree[now].flag_=,tree[now].if_=false;
} void tree_build(LL now,LL l,LL r)
{
tree[now].l=l,tree[now].r=r;
if(l==r)
{
read_int(tree[now].dis);
tree[now].max_=tree[now].dis;
tree[now].min_=tree[now].dis;
return ;
}
tree[now].mid=(l+r)>>;
tree_build(now<<,l,tree[now].mid);
tree_build(now<<|,tree[now].mid+,r);
tree_up(now);
} void tree_change(LL now,LL l,LL r,LL x)
{
if(tree[now].l==l&&tree[now].r==r)
{
if(tree[now].if_) tree[now].flag_+=x;
else tree[now].flag+=x;
tree[now].dis+=(r-l+)*x;
tree[now].max_+=x;
tree[now].min_+=x;
return ;
}
if(tree[now].flag||tree[now].if_) tree_down(now);
if(l>tree[now].mid) tree_change(now<<|,l,r,x);
else if(r<=tree[now].mid) tree_change(now<<,l,r,x);
else
{
tree_change(now<<,l,tree[now].mid,x);
tree_change(now<<|,tree[now].mid+,r,x);
}
tree_up(now);
} void tree_change_(LL now,LL l,LL r,LL x)
{
if(tree[now].l==l&&tree[now].r==r)
{
tree[now].if_=true;
tree[now].flag_=x;
tree[now].dis=(r-l+)*x;
tree[now].max_=x;
tree[now].min_=x;
return ;
}
if(tree[now].flag||tree[now].if_) tree_down(now);
if(l>tree[now].mid) tree_change_(now<<|,l,r,x);
else if(r<=tree[now].mid) tree_change_(now<<,l,r,x);
else
{
tree_change_(now<<,l,tree[now].mid,x);
tree_change_(now<<|,tree[now].mid+,r,x);
}
tree_up(now);
} LL tree_query(LL now,LL l,LL r,LL type)
{
if(tree[now].l==l&&tree[now].r==r)
{
if(type==) return tree[now].dis;
if(type==) return tree[now].max_;
if(type==) return tree[now].min_;
}
if(tree[now].flag||tree[now].if_) tree_down(now);
tree_up(now);
if(l>tree[now].mid) return tree_query(now<<|,l,r,type);
else if(r<=tree[now].mid) return tree_query(now<<,l,r,type);
else
{
if(type==) return tree_query(now<<,l,tree[now].mid,type)+tree_query(now<<|,tree[now].mid+,r,type);
if(type==) return max(tree_query(now<<,l,tree[now].mid,type),tree_query(now<<|,tree[now].mid+,r,type));
if(type==) return min(tree_query(now<<,l,tree[now].mid,type),tree_query(now<<|,tree[now].mid+,r,type));
}
} int main()
{
read_int(n),read_int(m);
tree_build(,,n);
char ch[];
for(LL i=;i<=m;i++)
{
cin>>ch;
LL x,y,z;
if(ch[]=='a')
{
read_int(x),read_int(y),read_int(z);
tree_change(,x,y,z);
}
else if(ch[]=='s')
{
if(ch[]=='e')
{
read_int(x),read_int(y),read_int(z);
tree_change_(,x,y,z);
}
else
{
read_int(x),read_int(y);
cout<<tree_query(,x,y,);
putchar('\n');
}
}
else if(ch[]=='m')
{
if(ch[]=='a')
{
read_int(x),read_int(y);
cout<<tree_query(,x,y,);
putchar('\n');
}
else
{
read_int(x),read_int(y);
cout<<tree_query(,x,y,);
putchar('\n');
}
}
}
return ;
}
AC日记——线段树练习5 codevs 4927的更多相关文章
- AC日记——线段树练习三 codevs 1082 (分块尝试)
线段树练习 3 思路: 分块: 来,上代码: #include <cmath> #include <cstdio> #include <cstring> #incl ...
- AC日记——线段树练习4 codevs 4919
4919 线段树练习4 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 给你N个数,有两种操作 ...
- hdu 4117 -- GRE Words (AC自动机+线段树)
题目链接 problem Recently George is preparing for the Graduate Record Examinations (GRE for short). Obvi ...
- hdu 4117 GRE Words (ac自动机 线段树 dp)
参考:http://blog.csdn.net/no__stop/article/details/12287843 此题利用了ac自动机fail树的性质,fail指针建立为树,表示父节点是孩子节点的后 ...
- HDU 5069 Harry And Biological Teacher(AC自动机+线段树)
题意 给定 \(n\) 个字符串,\(m\) 个询问,每次询问 \(a\) 字符串的后缀和 \(b\) 字符串的前缀最多能匹配多长. \(1\leq n,m \leq 10^5\) 思路 多串匹配,考 ...
- BZOJ2434:[NOI2011]阿狸的打字机(AC自动机,线段树)
Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的 ...
- T1081 线段树练习 2 codevs
http://codevs.cn/problem/1081/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数, ...
- 背单词(AC自动机+线段树+dp+dfs序)
G. 背单词 内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 给定一张包含N个单词的表,每个单词有个价值W.要求从中选出一个子序列使 ...
- AC日记——[ZJOI2008]树的统计Count bzoj 1036
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 15007 Solved: 6092[Submit ...
随机推荐
- Vim如何显示和关闭行号
显示行号: set nu 去除行号: set nonu
- GoF23种设计模式之行为型模式之策略模式
传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 1概述 定义一系列算法,把它们一个个都封装起来,并且让它们可以相互 ...
- Altium Designer入门学习笔记4:PCB设计中各层的含义
阻焊层:solder mask,是指板子上要上绿油的部分:因为它是负片输出,所以实际上有solder mask的部分实际效果并不上绿油,而是镀锡,呈银白色! 助焊层:paste mask,是机器贴片时 ...
- Educational Codeforces Round 53 (Rated for Div. 2) C Vasya and Robot 二分
题目:题目链接 思路:对于x方向距离与y方向距离之和大于n的情况是肯定不能到达的,另外,如果n比abs(x) + abs(y)大,那么我们总可以用UD或者LR来抵消多余的大小,所以只要abs(x) + ...
- bash实例
1写一个脚本,完成如下功能(使用函数):1.脚本使用格式:mkscript.sh [-D|--description "script description"] [-A|--aut ...
- 串口编程的相关API函数
用户使用函数CreateFile()创建与指定串口相关联的文件,然后可以使用该函数返回的文件句柄进行串口参数设置.• 01 HANDLE hModem; //定义串口句柄02 hModem=Creat ...
- day03_13 多分支if语句及作业
猜年龄升级版 age_of_princal = 56 guess_age = int( input("请输入您猜测的年龄") ) if guess_age == age_of_pr ...
- 移动端click时间、touch事件、tap事件详解
一.click 和 tap 比较 两者都会在点击时触发,但是在手机WEB端,click会有 200~300 ms,所以请用tap代替click作为点击事件. singleTap和doubleTap 分 ...
- cinema 4d 包括宝典 --- 改线 循环边 建模布线原则
cinema 4d 一.视图控制与物体控制 1.摇移 alt+鼠标左键 转圈看物体 改变角度 2.平移 alt +鼠标中键 不改变角度 移动 3.推拉 alt+鼠标右键 ...
- Matlab 二值图像label regions
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/52862719 Matlab提供了现成的 ...