[bzoj4293][PA2015]Siano
来源:互联网 发布:qq群网络原因上传失败 编辑:程序博客网 时间:2024/06/05 21:54
于是就此成为了权限狗2333
题目大意
有n棵草,第i棵草每天长高a[i],有m次操作每次会在某一天将所有超过某个高度的部分都砍掉,初始草的高度都是0,对于每次操作输出砍掉了多少。
题解
由于初始都是0,那么画一下图发现草高度的相对顺序是永远不会变的,于是可以直接用线段树维护,操作时先在线段树上二分,然后修改比较trick,懒标记维护的是这个区间的草上一次被砍掉是什么时候以及上次剩下的是多高,然后就可以直接维护了。
Code
#include<iostream>#include<cstring>#include<cmath>#include<algorithm>#include<cstdio>#include<map>#include<set>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;typedef long long LL;typedef double db;const int N = 500010;int n,m;int a[N];struct point{ LL sk,sb,adx,adb,rk,rb; int l,r;}tree[N*2];int tot;void build(int &now,int l,int r){ now=++tot; if (l==r){ tree[now].sk=tree[now].rk=a[l]; return; } int mid=(l+r)/2; build(tree[now].l,l,mid); build(tree[now].r,mid+1,r); tree[now].sk=tree[tree[now].l].sk+tree[tree[now].r].sk; tree[now].rk=tree[tree[now].r].rk;}void down(int now,int l,int r){ if (tree[now].adx>0){ int x=tree[now].l,mid=(l+r)/2; tree[x].adx=tree[now].adx; tree[x].adb=tree[now].adb; tree[x].sb=tree[now].adb*(mid-l+1)-tree[x].sk*tree[now].adx; tree[x].rb=tree[now].adb-tree[x].rk*tree[now].adx; x=tree[now].r; tree[x].adx=tree[now].adx; tree[x].adb=tree[now].adb; tree[x].sb=tree[now].adb*(r-mid)-tree[x].sk*tree[now].adx; tree[x].rb=tree[now].adb-tree[x].rk*tree[now].adx; tree[now].adx=tree[now].adb=0; }}int getw(int now,int l,int r,LL x,LL v){ if (tree[now].rk*x+tree[now].rb>=v)return r; if (l==r)return 0; down(now,l,r); int mid=(l+r)/2; int ans=getw(tree[now].l,l,mid,x,v); if (ans==mid)ans=max(ans,getw(tree[now].r,mid+1,r,x,v)); return ans;}LL change(int now,int l,int r,int w,LL x,LL v){ if (r<=w){ LL ans=tree[now].sk*x+tree[now].sb-v*(r-l+1); tree[now].sb=v*(r-l+1)-tree[now].sk*x; tree[now].rb=v-tree[now].rk*x; tree[now].adx=x; tree[now].adb=v; return ans; } down(now,l,r); int mid=(l+r)/2; LL ans; if (w<=mid)ans=change(tree[now].l,l,mid,w,x,v); else ans=change(tree[now].l,l,mid,w,x,v)+change(tree[now].r,mid+1,r,w,x,v); tree[now].sb=tree[tree[now].l].sb+tree[tree[now].r].sb; tree[now].rb=tree[tree[now].r].rb; return ans;}int main(){ scanf("%d%d",&n,&m); fo(i,1,n)scanf("%d",&a[i]); sort(a+1,a+1+n); fo(i,1,n/2)swap(a[i],a[n-i+1]); int rt; build(rt,1,n); fo(i,1,m){ LL t,v; scanf("%lld%lld",&t,&v); int w=getw(1,1,n,t,v); if (w==0)printf("0\n"); else printf("%lld\n",change(1,1,n,w,t,v)); } return 0;}
0 0
- 【PA2015】【BZOJ4293】Siano
- [bzoj4293][PA2015]Siano
- BZOJ4293 [PA2015]Siano(线段树)
- 【线段树】【树】[BZOJ4293][HYSBZ4293][PA2015]Siano
- 【线段树】【二分】[PA2015][BZOJ4293]Siano
- 4293: [PA2015]Siano 线段树
- bzoj 4293: [PA2015]Siano(线段树)
- 【PA2015】【BZOJ4291】Kieszonkowe
- 【bzoj4291】【PA2015】【Kieszonkowe】【贪心】
- BZOJ4291: [PA2015]Kieszonkowe
- BZOJ 4296 PA2015 Mistrzostwa
- 【PA2015】【BZOJ4294】Fibonacci
- 【PA2015】【BZOJ4296】Mistrzostwa
- 4291: [PA2015]Kieszonkowe|贪心
- 【PA2015】【BZOJ4297】Rozstaw szyn
- BZOJ_P4291 [PA2015]Kieszonkowe(贪心)
- [pa2015]Fibonacci 解题报告
- 4291: [PA2015]Kieszonkowe
- JSP 日期处理
- java 多线程学习之多生产者多消费者产生的线程安全问题分析与解决:Lock和Condition
- 自定义密码输入EditTextLayout
- Animator 实现 FloatActionBar 点击弹出多个FloatActionBar
- Cloud云深网谈:空手套白狼的智慧
- [bzoj4293][PA2015]Siano
- 几何着色器
- uboot 通用board_init_f实现
- Wdate 小知识点
- 数据结构之链表
- iOS使用StroryBoard页面跳转及传值
- JSP 页面重定向
- Swift——分支guard的使用
- Android群英传 第一章