最假女选手

Time Limit: 50 Sec  Memory Limit: 128 MB
Submit: 480  Solved: 118
[Submit][Status][Discuss]

Description

在刚刚结束的水题嘉年华的压轴节目放水大赛中,wyywyy如愿以偿的得到了最假女选手的奖项。但是作为主办人的
C_SUNSHINE为了证明wyywyy确实在放水,决定出一道基础题考察wyywyy的姿势水平。给定一个长度为 N序列,编号
从1 到 N。要求支持下面几种操作:
1.给一个区间[L,R] 加上一个数x 
2.把一个区间[L,R] 里小于x 的数变成x 
3.把一个区间[L,R] 里大于x 的数变成x 
4.求区间[L,R] 的和
5.求区间[L,R] 的最大值
6.求区间[L,R] 的最小值

Input

第一行一个整数 N表示序列长度。
第二行N 个整数Ai 表示初始序列。
第三行一个整数M 表示操作个数。
接下来M 行,每行三或四个整数,第一个整数Tp 表示操作类型,接下来L,R,X 或L,R 表述操作数。
1<=tp<=6,N,M<=5*10^5,|Ai|<=10^8
Tp=1时,|x|<=1000
Tp=2或3时,|x|<=10^8

Output

对于每个4,5,6类型的操作输出一行一个整数表示答案。

Sample Input

2
1 2
2
2 1 2 2
4 1 2

Sample Output

4

HINT

 

题解:吉利线段树的模板题

https://pan.baidu.com/s/1o7xSSQ2

 #include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<map> #define ll long long
#define inf 1000000007
#define N 500007
#define ls p<<1
#define rs p<<1|1
using namespace std;
inline ll read()
{
ll x=,f=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-;ch=getchar();}
while(isdigit(ch)){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,m;
int mx[N<<],cx[N<<],sx[N<<];//区间最大值,最大值个数 ,区间严格次大值
int mn[N<<],cn[N<<],sn[N<<];//区间最小值,最小值个数 ,区间严格次小值
int add[N<<];//区间tag标记
ll sum[N<<];//区间和 inline void push_up(int p)
{
sum[p]=sum[ls]+sum[rs]; if (mx[ls]>mx[rs]) mx[p]=mx[ls],cx[p]=cx[ls],sx[p]=max(sx[ls],mx[rs]);
if (mx[ls]<mx[rs]) mx[p]=mx[rs],cx[p]=cx[rs],sx[p]=max(mx[ls],sx[rs]);
if (mx[ls]==mx[rs]) mx[p]=mx[ls],cx[p]=cx[ls]+cx[rs],sx[p]=max(sx[ls],sx[rs]); if (mn[ls]<mn[rs]) mn[p]=mn[ls],cn[p]=cn[ls],sn[p]=min(sn[ls],mn[rs]);
if (mn[ls]>mn[rs]) mn[p]=mn[rs],cn[p]=cn[rs],sn[p]=min(mn[ls],sn[rs]);
if (mn[ls]==mn[rs]) mn[p]=mn[ls],cn[p]=cn[ls]+cn[rs],sn[p]=min(sn[ls],sn[rs]);
// cout<<sum[p]<<endl;
}
inline void push_down(int p,int l,int r)
{
if (add[p])
{
int mid=(l+r)>>;
mx[ls]+=add[p],sx[ls]+=add[p],mn[ls]+=add[p],sn[ls]+=add[p],sum[ls]+=(mid-l+)*add[p],add[ls]+=add[p];
mx[rs]+=add[p],sx[rs]+=add[p],mn[rs]+=add[p],sn[rs]+=add[p],sum[rs]+=(r-mid)*add[p],add[rs]+=add[p];
add[p]=;
}
if (mx[ls]>mx[p])
{
if (mn[ls]==mx[ls]) mn[ls]=mx[p];
if (sn[ls]==mx[ls]) sn[ls]=mx[p];
sum[ls]+=1ll*(mx[p]-mx[ls])*cx[ls],mx[ls]=mx[p];
}
if (mx[rs]>mx[p])
{
if (mn[rs]==mx[rs]) mn[rs]=mx[p];
if (sn[rs]==mx[rs]) sn[rs]=mx[p];
sum[rs]+=1ll*(mx[p]-mx[rs])*cx[rs],mx[rs]=mx[p];
}
if (mn[ls]<mn[p])
{
if (mx[ls]==mn[ls]) mx[ls]=mn[p];
if (sx[ls]==mn[ls]) sx[ls]=mn[p];
sum[ls]+=1ll*(mn[p]-mn[ls])*cn[ls],mn[ls]=mn[p];
}
if (mn[rs]<mn[p])
{
if (mx[rs]==mn[rs]) mx[rs]=mn[p];
if (sx[rs]==mn[rs]) sx[rs]=mn[p];
sum[rs]+=1ll*(mn[p]-mn[rs])*cn[rs],mn[rs]=mn[p];
}
}
void build(int p,int l,int r)
{
if (l==r)
{
mx[p]=mn[p]=sum[p]=read();
cx[p]=cn[p]=;
sx[p]=-inf,sn[p]=inf;
return;
}
int mid=(l+r)>>;
build(ls,l,mid),build(rs,mid+,r);
push_up(p);
}
void vadd(int p,int l,int r,int x,int y,int z)
{
if (l==x&&y==r)
{
mx[p]+=z,sx[p]+=z,mn[p]+=z,sn[p]+=z;
sum[p]+=1ll*(r-l+)*z,add[p]+=z;
return;
}
push_down(p,l,r);
int mid=(l+r)>>;
if (y<=mid) vadd(ls,l,mid,x,y,z);
else if (x>mid) vadd(rs,mid+,r,x,y,z);
else vadd(ls,l,mid,x,mid,z),vadd(rs,mid+,r,mid+,y,z);
push_up(p);
}
void vmax(int p,int l,int r,int x,int y,int z)
{
//cout<<p<<" "<<l<<" "<<r<<" "<<x<<" "<<y<<" "<<z<<endl;
if (mn[p]>=z) return;
if (l==x&&y==r&&sn[p]>z)
{
//cout<<p<<" "<<l<<" "<<r<<endl;
if (mx[p]==mn[p]) mx[p]=z;
if (sx[p]==mn[p]) sx[p]=z;
sum[p]+=1ll*(z-mn[p])*cn[p],mn[p]=z;
return;
}
push_down(p,l,r);
int mid=(l+r)>>;
if (y<=mid) vmax(ls,l,mid,x,y,z);
else if (x>mid) vmax(rs,mid+,r,x,y,z);
else vmax(ls,l,mid,x,mid,z),vmax(rs,mid+,r,mid+,y,z);
push_up(p);
}
void vmin(int p,int l,int r,int x,int y,int z)
{
if (mx[p]<=z) return;
if (l==x&&y==r&&sx[p]<z)
{
//cout<<l<<" "<<r<<" "<<p<<endl;
if (mn[p]==mx[p]) mn[p]=z;
if (sn[p]==mx[p]) sn[p]=z;
sum[p]+=1ll*(z-mx[p])*cx[p],mx[p]=z;
// cout<<sum[p]<<" "<<l<<" "<<r<<" "<<p<<endl;
return;
}
push_down(p,l,r);
int mid=(l+r)>>;
if (y<=mid) vmin(ls,l,mid,x,y,z);
else if (x>mid) vmin(rs,mid+,r,x,y,z);
else vmin(ls,l,mid,x,mid,z),vmin(rs,mid+,r,mid+,y,z);
// cout<<l<<" "<<r<<" "<<sum[p]<<endl;
push_up(p);
// cout<<p<<" "<<l<<" "<<r<<" "<<sum[p]<<" "<<sum[ls]<<" "<<sum[rs]<<endl;
}
ll qsum(int p,int l,int r,int x,int y)
{
//cout<<l<<" "<<r<<" "<<p<<" "<<sum[p]<<endl;
if (l==x&&y==r) return sum[p];
push_down(p,l,r);
int mid=(l+r)>>;
if (y<=mid) return qsum(ls,l,mid,x,y);
else if (x>mid) return qsum(rs,mid+,r,x,y);
else return qsum(ls,l,mid,x,mid)+qsum(rs,mid+,r,mid+,y);
}
int qmax(int p,int l,int r,int x,int y)
{
if (l==x&&y==r) return mx[p];
push_down(p,l,r);
int mid=(l+r)>>;
if (y<=mid) return qmax(ls,l,mid,x,y);
else if (x>mid) return qmax(rs,mid+,r,x,y);
else return max(qmax(ls,l,mid,x,mid),qmax(rs,mid+,r,mid+,y));
}
int qmin(int p,int l,int r,int x,int y)
{
if (l==x&&y==r) return mn[p];
push_down(p,l,r);
int mid=(l+r)>>;
if (y<=mid) return qmin(ls,l,mid,x,y);
else if (x>mid) return qmin(rs,mid+,r,x,y);
else return min(qmin(ls,l,mid,x,mid),qmin(rs,mid+,r,mid+,y));
}
int main()
{
freopen("fzy.in","r",stdin);
freopen("fzy.out","w",stdout); n=read();
build(,,n);
m=read();
while(m--)
{
int opt=read(),x=read(),y=read(),z;
if (opt==) z=read(),vadd(,,n,x,y,z);
if (opt==) z=read(),vmax(,,n,x,y,z);
if (opt==) z=read(),vmin(,,n,x,y,z);
if (opt==) printf("%lld\n",qsum(,,n,x,y));
if (opt==) printf("%d\n",qmax(,,n,x,y));
if (opt==) printf("%d\n",qmin(,,n,x,y));
}
}

bzoj 4695 最假女选手 吉利线段树的更多相关文章

  1. BZOJ.4695.最假女选手(线段树 Segment tree Beats!)

    题目链接 区间取\(\max,\ \min\)并维护区间和是普通线段树无法处理的. 对于操作二,维护区间最小值\(mn\).最小值个数\(t\).严格次小值\(se\). 当\(mn\geq x\)时 ...

  2. BZOJ 4695 最假女选手 线段树

    题意: 给定一个长度为 N序列,编号从1 到 N.要求支持下面几种操作: 1.给一个区间[L,R] 加上一个数x  2.把一个区间[L,R] 里小于x 的数变成x  3.把一个区间[L,R] 里大于x ...

  3. bzoj 4695: 最假女选手 && Gorgeous Sequence HDU - 5306 && (bzoj5312 冒险 || 小B的序列) && bzoj4355: Play with sequence

    算导: 核算法 给每种操作一个摊还代价(是手工定义的),给数据结构中某些东西一个“信用”值(不是手动定义的,是被动产生的),摊还代价等于实际代价+信用变化量. 当实际代价小于摊还代价时,增加等于差额的 ...

  4. bzoj 4695: 最假女选手

    ……一道丧病线段树膜板题…… 被常数卡的死去活来……QAQ 学到了些奇技淫巧:把取min标记 和 区间最小值 合并 可以快很多…… #include <bits/stdc++.h> #de ...

  5. 2018.07.27 bzoj4695: 最假女选手(线段树)

    传送门 线段树好题 支持区间加,区间取min" role="presentation" style="position: relative;"> ...

  6. (WC2016模拟十一)【BZOJ4695】最假女选手

    ps:好久没更博啦……这几天连着有模拟赛,等初赛前后休息的时候来疯狂补坑吧……顺便补一下前面的数论啥的? 题解: mdzz我场上写了个15分暴力长度跟标算差不多... 线段树大法好啊!这题听说很多人做 ...

  7. [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+并查集+启发式合并)

    [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+启发式合并) 题面 给出一个n个节点m条边的森林,每个节点都有一个权值.有两种操作: Q x y k查询点x到点y路径上所有的权值中 ...

  8. BZOJ4695 最假女选手(势能线段树)

    BZOJ题目传送门 终于体会到初步掌握势能分析思想的重要性了. 一开始看题,感觉套路还是很一般啊qwq.直接在线段树上维护最大值和最小值,每次递归更新的时候,如果不能完全覆盖就暴力递归下去.挺好写的欸 ...

  9. 【bzoj4695】最假女选手 线段树区间最值操作

    题目描述 给定一个长度为 N 序列,编号从 1 到 N .要求支持下面几种操作:1.给一个区间[L,R] 加上一个数x 2.把一个区间[L,R] 里小于x 的数变成x 3.把一个区间[L,R] 里大于 ...

随机推荐

  1. 【shell 练习5】编写简单的多级菜单

    一.简单的多级菜单 [root@web129 ~]# cat menu.sh #!/bin/bash #shell菜单演示 function menu() { echo -e `date` cat & ...

  2. POJ 2455 Secret Milking Machine(最大流+二分)

    Description Farmer John is constructing a new milking machine and wishes to keep it secret as long a ...

  3. 你代码写得这么丑,一定是因为你长得不好看----panboo第一篇博客

    一.个人介绍 我叫潘博,软嵌162,学号1613072055. 以“panboo”名称混迹于各大开源IT论坛与博客. 除了编程,我的最大爱好是篮球与健身,热衷于各种IT技术与运动. 我做过的软件项目有 ...

  4. 第一届"进化论杯"月赛 解题报告

    Problem A: derivative 思路:水题.算出二阶导数,直接 printf 结果. 在求出二阶导数后可以不立刻化简,此时式中带有大量 e^(-x) 项.此时直接可以代入 ln|x0|,把 ...

  5. Divide two integers without using multiplication, division and mod operator.

    描述 不能使用乘法.除法和取模(mod)等运算,除开两个数得到结果,如果内存溢出则返回Integer类型的最大值.解释一下就是:输入两个数,第一个数是被除数dividend,第二个是除数divisor ...

  6. 敏捷冲刺Day2

    一. 每日会议 1. 照片 2. 昨日完成工作 网页设计与实现的完善 服务器的搭建前期--申请域名 激活域名 搭建服务器 分析接下来的任务与进度 总结前两天的工作 对产品的进一步展望 3. 今日完成工 ...

  7. Filezilla 绿色版 禁止升级 能用。

    FileZilla还是挺好用的,但是如果钟情于 绿色版的话,肯定首选是 免安装绿色版.但是呢,能找到的所谓的免升级 绿色版,都不能用.只要是打开软件了,就会在你还没有设置更新之前,就已经升级号了.并且 ...

  8. lucene 学习之基础篇

    一.什么是全文索引 全文检索首先将要查询的目标文档中的词提取出来,组册索引(类似书的目录),通过查询索引达到搜索目标文档的目的,这种先建立索引,再对索引进行搜索的过程就叫全文索引. 从图可以看出做全文 ...

  9. [BinaryTree] 最大堆的类实现

    堆的定义: 最大树(最小树):每个结点的值都大于(小于)或等于其子结点(如果有的话)值的树.最大堆(最小堆):最大(最小)的完全二叉树. 最大堆的抽象数据结构: class MaxHeap { pri ...

  10. 【Python】Python 新式类介绍

    本文转载自:kaka_ace's blog 我们使用 Python 开发时, 会遇到 class A 和 class A(object) 的写法, 这在 Python2 里是有概念上和功能上的区别, ...