多校训练2HDU 6047 Maximum Sequence
Posted shulin~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多校训练2HDU 6047 Maximum Sequence相关的知识,希望对你有一定的参考价值。
http://acm.hdu.edu.cn/showproblem.php?pid=6047
【题意】
- 给定两个长度为n的序列a和b,现在要通过一定的规则找到可行的a_n+1.....a_2n,求sum{a_n+1.....a_2n}的最大值
- 每次从序列b中选择一个数bk,那么构造的ai就是max{aj -j},其中bk<=j<i
- 每个bk最多用一次
【思路】
- 首先我们需要的是aj-j
- 可以贪心,即对于当前要构造的数ai,尽可能找bk使得能够取得最大的aj-j
- 线段树区间查询最优值+单点更新
- 把b排个序,对于每个b查询b[i]~n+i-1的最大值
【Accepted】
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 #include<cmath> 7 #define lson (i<<1) 8 #define rson (i<<1|1) 9 #include<vector> 10 #include<map> 11 using namespace std; 12 const int maxn=(25e4+5)*2; 13 typedef long long ll; 14 const ll mod=1e9+7; 15 const int inf=0x3f3f3f3f; 16 long long val[maxn]; 17 int a[maxn]; 18 int b[maxn]; 19 int n; 20 struct Seg 21 { 22 int l,r,lazy,val; 23 }tree[maxn<<2]; 24 25 void push_up(int i) 26 { 27 tree[i].val=max(tree[lson].val,tree[rson].val); 28 } 29 30 void push_down(int i) 31 { 32 if(tree[i].lazy==-1) 33 { 34 return; 35 } 36 tree[lson].lazy=tree[lson].val=tree[i].lazy; 37 tree[rson].lazy=tree[rson].val=tree[i].lazy; 38 tree[i].lazy=-1; 39 } 40 41 void Build(int l,int r,long long i=1) 42 { 43 tree[i].l=l; 44 tree[i].r=r; 45 tree[i].lazy=-1; 46 if(l==r) 47 { 48 tree[i].val=val[l]; 49 return; 50 } 51 push_down(i); 52 int mid=(tree[i].l+tree[i].r)>>1; 53 Build(l,mid,lson); 54 Build(mid+1,r,rson); 55 push_up(i); 56 } 57 58 int Query(int l,int r,int i=1) 59 { 60 if(tree[i].l==l&&tree[i].r==r) 61 { 62 return tree[i].val; 63 } 64 push_down(i); 65 int mid=(tree[i].l+tree[i].r)>>1; 66 if(r<=mid) 67 { 68 return Query(l,r,lson); 69 } 70 else if(l>mid) 71 { 72 return Query(l,r,rson); 73 } 74 else 75 { 76 return max(Query(l,mid,lson),Query(mid+1,r,rson)); 77 } 78 } 79 80 void Setval(int l,int r,int x,int i=1) 81 { 82 if(tree[i].l==l&&tree[i].r==r) 83 { 84 tree[i].lazy=tree[i].val=x; 85 return; 86 } 87 push_down(i); 88 int mid=(tree[i].l+tree[i].r)>>1; 89 if(r<=mid) 90 { 91 Setval(l,r,x,lson); 92 } 93 else if(l>mid) 94 { 95 Setval(l,r,x,rson); 96 } 97 else 98 { 99 Setval(l,mid,x,lson); 100 Setval(mid+1,r,x,rson); 101 } 102 push_up(i); 103 } 104 105 int main() 106 { 107 while(~scanf("%d",&n)) 108 { 109 for(int i=1;i<=2*n;i++) 110 { 111 val[i]=-inf; 112 } 113 for(int i=1;i<=n;i++) 114 { 115 scanf("%d",&a[i]); 116 val[i]=a[i]-i; 117 } 118 Build(1,2*n); 119 for(int i=1;i<=n;i++) 120 { 121 scanf("%d",&b[i]); 122 } 123 sort(b+1,b+1+n); 124 ll ans=0; 125 b[0]=0; 126 for(int i=1;i<=n;i++) 127 { 128 int mmax=Query(b[i],n+i-1); 129 ans=(ans+(ll)mmax)%mod; 130 Setval(n+i,n+i,mmax-(n+i)); 131 } 132 cout<<ans<<endl; 133 } 134 return 0; 135 }
以上是关于多校训练2HDU 6047 Maximum Sequence的主要内容,如果未能解决你的问题,请参考以下文章
[Lyndon分解] HDU 6761 Minimum Index (2020多校训练)
hdu 4911 Inversion(归并排序求逆序对数)2014多校训练第5场