【JZOJ5409】Fantasy
来源:互联网 发布:金融电子化公司 知乎 编辑:程序博客网 时间:2024/06/08 06:33
Description
Y sera 陷入了沉睡,幻境中它梦到一个长度为N 的序列{Ai}。
对于这个序列的每一个子串,定义其幻境值为这个子串的和,现在Y sera 希望选择K 个不同的子串并使得这K 个子串的幻境值之和最大。
然而由于梦境中的种种限制,这些子串的长度必须在L 到R 之间。
你需要告诉她,最大的幻境值之和。
Solution
先对
还有一种与
Solution
与
#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)#define N 100010#define _ 1000000000#define ll long longusing namespace std;struct node{ ll s; int x,l,r;}tr[N*55];ll s[N];void update(int v){ tr[v].s=tr[tr[v].l].s+tr[tr[v].r].s; tr[v].x=tr[tr[v].l].x+tr[tr[v].r].x;}int rt[N],tot=0;void insert(int &v,int l,int r,int x){ tr[++tot]=tr[v],v=tot; if(l==r){ tr[v].s+=x,tr[v].x++; return; } int mid=((ll)l+r)/2; if(x<=mid) insert(tr[v].l,l,mid,x); else insert(tr[v].r,mid+1,r,x); update(v);}ll findsum(int v0,int v1,int l,int r,int x,int y){ if(l==x && r==y){ return tr[v0].s-tr[v1].s; } int mid=((ll)l+r)/2; if(y<=mid) return findsum(tr[v0].l,tr[v1].l,l,mid,x,y); else if(x>mid) return findsum(tr[v0].r,tr[v1].r,mid+1,r,x,y); else return findsum(tr[v0].l,tr[v1].l,l,mid,x,mid)+findsum(tr[v0].r,tr[v1].r,mid+1,r,mid+1,y);}int find(int v0,int v1,int l,int r,int x,int y){ if(l==x && r==y){ return tr[v0].x-tr[v1].x; } int mid=((ll)l+r)/2; if(y<=mid) return find(tr[v0].l,tr[v1].l,l,mid,x,y); else if(x>mid) return find(tr[v0].r,tr[v1].r,mid+1,r,x,y); else return find(tr[v0].l,tr[v1].l,l,mid,x,mid)+find(tr[v0].r,tr[v1].r,mid+1,r,mid+1,y);}int n,K,L,R;bool check(int x){ int cn=0; fo(i,1,n-L+1) { int l=i+L-2,r=min(i+R-1,n); if((ll)s[i-1]+x<=_*2) cn+=find(rt[r],rt[l],0,_*2,s[i-1]+x,_*2); } return cn>=K;}int main(){ freopen("fantasy.in","r",stdin); freopen("fantasy.out","w",stdout); scanf("%d %d %d %d",&n,&K,&L,&R); fo(i,1,n) { int x; scanf("%d",&x); s[i]=s[i-1]+x; rt[i]=rt[i-1],insert(rt[i],0,_*2,s[i]+_); } int l=0,r=_*2; while(l+1<r){ int mid=((ll)l+r)/2; if(check(mid)) l=mid; else r=mid; } if(check(r)) l=r; int cn=0; ll ans=0; fo(i,1,n-L+1) { int p=i+L-2,q=min(i+R-1,n); int tmp=find(rt[q],rt[p],0,_*2,s[i-1]+l,_*2); cn+=tmp; ans+=findsum(rt[q],rt[p],0,_*2,s[i-1]+l,_*2)-(s[i-1]+_)*tmp; } if(cn>K) ans=ans-(cn-K)*(l-_); printf("%lld",ans);}
阅读全文
1 0
- 【JZOJ5409】Fantasy
- Jzoj5409 Fantasy
- JZOJ5409. 【NOIP2017提高A组集训10.21】Fantasy
- Final Fantasy
- Fantasy of a Summation
- Fantasy of a Summation
- Fantasy Cricket UVA
- lightoj - 1299 - Fantasy Cricket - dp
- lightoj1213 - Fantasy of a Summation
- LightOJ1213 Fantasy of a Summation
- [NOIP2017模拟]Fantasy Strange Tree
- [NOIP模拟]Fantasy Strange Tree
- Wallpapers Final Fantasy XII Pack 1
- I live in a world of fantasy
- BirthdayManager-Demo with a Fantasy Vista
- ZOJ 3698 Carrot Fantasy (大模拟)
- lightOJ 1213 Fantasy of a Summation
- LightOJ 1213 Fantasy of a Summation
- 我的2018校招
- unity机器学习之unity和python环境搭建
- Ajax学习中的一些总结
- Windows上Navicat工具远程连接PostgreSQL数据库
- QSqlQueryModel/QSqlTableModel 仅能获取256行的问题
- 【JZOJ5409】Fantasy
- Combinatorics——HDUOJ 1027
- aix中如何缩小默认的交换空间
- 095: 复习习题 求导题型 Case1:显函数求导;Case2:隐函数求导;Case3:参数方程确定的函数
- 最短路径算法 -Dijkstra算法
- SPOJTime Limit Exceeded 高维前缀和优化+ dp
- Linux系统之下的基本gdb调试
- 如何安装Lavarel How to install Lavarel?
- C6748定时器64位模式