JZOJ5419. 【NOIP2017提高A组集训10.24】线段树
来源:互联网 发布:js 数组 push pop 编辑:程序博客网 时间:2024/06/05 07:58
很烦人的线段树= =。不过理解了以后还是挺好打的,就是太长。
具体的话就是维护每一个区间内到左端点右端点的最小代价和最左边,最右边的可用的位置,然后直接更新就好了,至于查询的话,就是查询中位数咯,查询一下中位数左右两边最靠近他的可用的点,然后取个代价最小的。
#include<cstdio>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)#define mp(x,y) make_pair(x,y)using namespace std;const int N=2e5+5;typedef long long ll;const ll inf=1e17;int n,m,a[N];struct tree{ int lb,rb,lazy,sb; ll tol,tor,s;}t[N*5];struct node{ int x; ll y;};int read(){ int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}inline void pushup(int x,int l,int r){ int mid=(l+r)>>1; t[x].lb=t[x<<1].lb?t[x<<1].lb:t[x<<1|1].lb; t[x].rb=t[x<<1|1].rb?t[x<<1|1].rb:t[x<<1].rb; t[x].sb=t[x<<1].sb+t[x<<1|1].sb; t[x].s=t[x<<1].s+t[x<<1|1].s; t[x].tol=t[x<<1].tol+t[x<<1|1].tol+1ll*t[x<<1|1].s*(mid-l+1); t[x].tor=t[x<<1|1].tor+t[x<<1].tor+1ll*t[x<<1].s*(r-mid);}inline void pushdown(int x,int l,int r){ if (l==r||t[x].lazy==-1) return; int lazy=t[x].lazy; int mid=(l+r)>>1; t[x].lazy=-1; if (!lazy) { t[x<<1].lazy=t[x<<1|1].lazy=lazy; t[x<<1].lb=l; t[x<<1].rb=mid; t[x<<1].sb=mid-l+1; t[x<<1|1].lb=mid+1; t[x<<1|1].rb=r; t[x<<1|1].sb=r-mid; } else { t[x<<1].lazy=t[x<<1|1].lazy=lazy; t[x<<1].lb=t[x<<1].rb=t[x<<1].sb=0; t[x<<1|1].lb=t[x<<1|1].rb=t[x<<1|1].sb=0; }}inline void build(int x,int l,int r){ if (l==r) { t[x].s=a[l]; t[x].rb=t[x].lb=l; t[x].sb=1,t[x].lazy=-1; return; } int mid=(l+r)>>1; build(x<<1,l,mid); build(x<<1|1,mid+1,r); pushup(x,l,r);}inline void ins(int x,int l,int r,int pos,int v){ pushdown(x,l,r); if (l==r) { t[x].s+=1ll*v; return; } int mid=(l+r)>>1; if (pos<=mid)ins(x<<1,l,mid,pos,v); else ins(x<<1|1,mid+1,r,pos,v); pushup(x,l,r);}inline void change(int x,int l,int r,int l1,int r1,int ok){ //if (l1>r1)return; if (l==l1&&r==r1) { t[x].lazy=ok; if (!ok)t[x].lb=l,t[x].rb=r,t[x].sb=r-l+1; else t[x].lb=t[x].rb=t[x].sb=0; return; }pushdown(x,l,r); int mid=(l+r)>>1; if (r1<=mid)change(x<<1,l,mid,l1,r1,ok); else if (l1>mid)change(x<<1|1,mid+1,r,l1,r1,ok); else { change(x<<1,l,mid,l1,mid,ok); change(x<<1|1,mid+1,r,mid+1,r1,ok); } //change(x<<1,l,mid,l1,min(r1,mid),ok); //change(x<<1|1,mid+1,r,max(l1,mid+1),r1,ok); pushup(x,l,r);}inline int query(int x,int l,int r,ll kth){ if (l==r)return l; int mid=(l+r)>>1; if (t[x<<1].s>=kth)return query(x<<1,l,mid,kth); else return query(x<<1|1,mid+1,r,kth-t[x<<1].s);}node getlb(int x,int l,int r,int l1,int r1){ node ans; if (!t[x].sb||l1>r1)return ans=(node){0,inf}; pushdown(x,l,r); if (l==r)return ans=(node){l,0}; int mid=(l+r)>>1; if (t[x<<1].rb&&t[x<<1].rb>=l1) { node ans=getlb(x<<1,l,mid,l1,min(mid,r1)); if (ans.x) ans.y+=t[x<<1|1].tol+1ll*t[x<<1|1].s*(mid-ans.x+1); return ans; } else { node ans=getlb(x<<1|1,mid+1,r,max(l1,mid+1),r1); if (ans.x) ans.y+=t[x<<1].tor+1ll*t[x<<1].s*(ans.x-mid); return ans; }}node getrb(int x,int l,int r,int l1,int r1){ node ans; if (!t[x].sb||l1>r1)return ans=(node){0,inf}; pushdown(x,l,r); if (l==r)return ans=(node){l,0}; int mid=(l+r)>>1; if (t[x<<1|1].lb&&t[x<<1|1].lb<=r1) { node ans=getrb(x<<1|1,mid+1,r,max(l1,mid+1),r1); if (ans.x) ans.y+=t[x<<1].tor+1ll*t[x<<1].s*(ans.x-mid); return ans; } else { node ans=getrb(x<<1,l,mid,l1,min(mid,r1)); if (ans.x) ans.y+=t[x<<1|1].tol+1ll*t[x<<1|1].s*(mid-ans.x+1); return ans; }}int main(){ freopen("position.in","r",stdin); freopen("position.out","w",stdout); n=read(),m=read(); ll tot=0; fo(i,1,n)a[i]=read(),tot+=a[i]; build(1,1,n); while(m--) { int op=read(),x=read(),y=read(); if (op==1)ins(1,1,n,x,y),tot+=y; if (op==2)ins(1,1,n,x,-y),tot-=y; if (op==3)change(1,1,n,x,y,0); if (op==4)change(1,1,n,x,y,1); int mid=query(1,1,n,(tot+1)/2); node l=getrb(1,1,n,1,mid); node r=getlb(1,1,n,mid,n); if (!l.x&&!r.x)printf("-1\n"); else { if (l.y<=r.y)printf("%d\n",l.x); else printf("%d\n",r.x); } }}
阅读全文
0 0
- JZOJ5419. 【NOIP2017提高A组集训10.24】线段树
- JZOJ5419. 【NOIP2017提高A组集训10.24】筹备计划
- JZOJ5417. 【NOIP2017提高A组集训10.24】 二维线段树
- 【NOIP2017提高A组集训10.24】合影
- 【JZOJ 5417】【NOIP2017提高A组集训10.24】方阵
- 【JZOJ 5418】【NOIP2017提高A组集训10.24】合影
- 【JZOJ 5419】【NOIP2017提高A组集训10.24】筹备计划
- JZOJ5417. 【NOIP2017提高A组集训10.24】方阵
- JZOJ5418. 【NOIP2017提高A组集训10.24】合影
- JZOJ 5417. 【NOIP2017提高A组集训10.24】方阵
- JZOJ 5419. 【NOIP2017提高A组集训10.24】筹备计划
- jzoj5417【NOIP2017提高A组集训10.24】方阵
- 【NOIP2017提高A组集训10.21】Dark
- 【NOIP2017提高A组集训10.21】Fantasy
- 【NOIP2017提高A组集训10.21】 总结
- 【NOIP2017提高A组集训10.21】 总结
- 【NOIP2017提高A组集训10.21】Fantasy
- 【NOIP2017提高A组集训10.22】友谊
- Intellij Idea Linux环境下 新建Maven(java)和Scala工程
- java实现个人所得税计算
- 二维码的生成细节和原理
- dedecms常用标签
- GANs正在多个层面有所突破
- JZOJ5419. 【NOIP2017提高A组集训10.24】线段树
- L1-008. 求整数段和
- js取项目上下文
- mark
- 抽象类
- 指针数组与数组指针详解
- 数据库存储过程,触发器,游标,函数
- 浅析web服务器与浏览器的实现原理
- ldap 教程