[Codeforces773E] [线段树] [找规律] Blog Post Rating
来源:互联网 发布:淘宝首页图片大小 编辑:程序博客网 时间:2024/05/18 01:29
题意大概是
有一个博客,初始赞数为0,每个人会浏览这篇博客,如果这个人期望的赞数大于这边博客的赞数,他就会赞这篇博客,如果小于这篇博客,就踩一下(博客赞数-1),相同就不操作。询问对于每个i,1~i的人按照一个顺序浏览,求一种顺序使得博客最后的赞数最大,输出这个最大的赞数。
先瞎猜一下,这1~i个人肯定是按照期望的赞数升序访问最优。 然后写个暴力交一下,发现T了,说明这个结论是对的
那么只要维护一下这个序列就可以了。可以用权值线段树维护。
考虑怎么求这个按照这个升序顺序访问能得到的答案。
首先
用
展开展开展开发现一个区间
那么每个区间维护一下
#include <cstdio>#include <iostream>#include <algorithm>#define N 500010using namespace std;typedef pair<int,int> parii;int n;int a[N];parii b[N];struct func{ int mn,tot; int val(int x){ return min(x+tot,mn); } friend func operator *(func a,func b){ a.tot+=b.tot; a.mn=min(b.mn,a.mn+b.tot); return a; }};struct seg{ int l,r,mx; func f;}T[N<<3];void Build(int g,int l,int r){ T[g].l=l; T[g].r=r; T[g].mx=-(1<<30); T[g].f.tot=0; T[g].f.mn=1<<30; if(l==r) return ; int mid=l+r>>1; Build(g<<1,l,mid); Build(g<<1|1,mid+1,r); T[g].f=T[g<<1].f*T[g<<1|1].f;}void Update(int g,int x,int y){ T[g].mx=max(T[g].mx,y); if(T[g].l==T[g].r){ T[g].f.tot++; T[g].f.mn=y; return ; } int mid=T[g].l+T[g].r>>1; if(x<=mid) Update(g<<1,x,y); else Update(g<<1|1,x,y); T[g].f=T[g<<1].f*T[g<<1|1].f;}int Calc(int g,int l,int r){ if(T[g].l==l&&T[g].r==r) return T[g].f.tot; int mid=T[g].l+T[g].r>>1; if(r<=mid) return Calc(g<<1,l,r); if(l>mid) return Calc(g<<1|1,l,r); return Calc(g<<1,l,mid)+Calc(g<<1|1,mid+1,r);}int Find(int g,int l,int r){ if(T[g].l==l&&T[g].r==r) return T[g].mx; int mid=T[g].l+T[g].r>>1; if(r<=mid) return Find(g<<1,l,r); if(l>mid) return Find(g<<1|1,l,r); return max(Find(g<<1,l,mid),Find(g<<1|1,mid+1,r));}func Query(int g,int l,int r){ if(T[g].l==l&&T[g].r==r) return T[g].f; int mid=T[g].l+T[g].r>>1; if(r<=mid) return Query(g<<1,l,r); if(l>mid) return Query(g<<1|1,l,r); return Query(g<<1,l,mid)*Query(g<<1|1,mid+1,r);}inline bool check(int x){ int num=Calc(1,1,x),last=Find(1,1,x); return last<=-num;}int main(){ freopen("1.in","r",stdin); freopen("1.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=parii(a[i],i); sort(b+1,b+1+n); for(int i=1;i<=n;i++) a[b[i].second]=i; Build(1,1,n); for(int i=1;i<=n;i++){ Update(1,a[i],b[a[i]].first); int L=1,R=n,mid,cur=-1; while(L<=R) check(mid=L+R>>1)?L=(cur=mid)+1:R=mid-1; if(cur==-1) printf("%d\n",Query(1,1,n).val(0)); else{ int num=Calc(1,1,cur); if(cur==n){ printf("%d\n",-num); continue; } printf("%d\n",Query(1,cur+1,n).val(-num)); } } return 0;}
阅读全文
0 0
- [Codeforces773E] [线段树] [找规律] Blog Post Rating
- [线段树 杂题] Codeforces 806E VK Cup 2017 Round 3 E. Blog Post Rating
- hdu5239Doom 线段树+找规律
- HDU5239(线段树,找规律,快速乘法)
- HDU 5239 Doom 线段树+找规律
- ZOJ 3886 Nico Number(线段树单点更新+找规律)
- Codeforces Round #316 (Div. 2) C. Replacement 找规律 或 线段树
- 找规律
- 找规律!
- 找规律
- 找规律,
- 找规律
- 找规律
- 找规律
- 找规律
- 找规律
- 找规律
- 找规律
- 《java多线程编程技术核心》读书笔记11
- 第21课:Spark性能调优之系统资源使用原理和调优最佳实践
- 保持学习的态度
- 理论---mongoDB的常用操作
- MVP
- [Codeforces773E] [线段树] [找规律] Blog Post Rating
- uC/Probe 应用 uCOSIII 配置
- html设置行的水平对齐
- html设置行的垂直对齐
- nosql数据库中之redis数据库一揽子方案
- [leetCode刷题笔记]49. Group Anagrams
- 信息采集实现原理Curl一揽子方案
- html表格标题的垂直对齐方式
- CQOI位统计