zoukankan      html  css  js  c++  java
  • 4504: K个串 主席树+优先队列

    这道题因为有一个数在序列中出现多次只算一次的限制。我们可以这样搞。假设在当前题意下求给定右端点的区间最值。那么我们可以预处理出每个数前一次出现的位置pre[i] 。接下来从左到右加入每一个值,就是在 pre[i] + 1 —— i 这个区间内加上 v[i] 的值,这样就可以得到以当前 i 点为右端点的各个区间的值(很明显维护一下最值就好了)。接下来很明显有n个版本的线段树(如果你说一开始那个空的线段树也算一个版本的话,就有n+1个),那就要用主席树动态开点。而取第K大值的操作有点像超级钢琴,不过在这里要维护5元组吧! 分别是 区间左端点, 区间右端点, 区间最值点, 区间最值, 线段树版本。 没了!就这样!

     1 #include<cstdio>
     2 #include<queue>
     3 #include<iostream>
     4 #include<map>
     5 #define rep(i,j,k) for(register int i = j; i <= k; i++)
     6 #define maxn 100005
     7 #define ll long long
     8 #define inf 1ll * 10000000 * 10000000 
     9 using namespace std;
    10  
    11 inline int read() {
    12     int s = 0, t = 1; char c = getchar();
    13     while( !isdigit(c) ) { if( c == '-' ) t = -1; c = getchar(); }
    14     while( isdigit(c) ) s = s * 10 + c - 48, c = getchar();
    15     return s * t;
    16 }
    17  
    18 int ql, qr, d, tot = 0, rot[maxn], c[maxn*100][2], pos[maxn*100]; ll sum[maxn*100], v[maxn*100]; 
    19 #define lc c[k][0]
    20 #define rc c[k][1]
    21 #define mid ((l+r)>>1)
    22 inline void build(int l,int r,int &k) {
    23     k = ++tot; pos[k] = l; 
    24     if( l == r ) return;
    25     build(l,mid,lc); build(mid+1,r,rc); 
    26 }  
    27 inline void update(int &k,int pre,int l,int r) {
    28     k = ++tot;
    29     sum[k] = sum[pre], v[k] = v[pre]; 
    30     lc = c[pre][0], rc = c[pre][1];
    31     if( ql <= l && r <= qr ) { sum[k] += d; v[k] += d; pos[k] = pos[pre]; return; }
    32     if( ql <= mid ) update(lc,c[pre][0],l,mid); else lc = c[pre][0];
    33     if( qr > mid ) update(rc,c[pre][1],mid+1,r); else rc = c[pre][1];
    34     if( sum[lc] > sum[rc] ) sum[k] = sum[lc] + v[k], pos[k] = pos[lc];
    35     else sum[k] = sum[rc] + v[k], pos[k] = pos[rc];
    36 }
    37  
    38 int wh; ll maxl;
    39 inline void querymx(int k,int l,int r, ll pd) {
    40     if( ql <= l && r <= qr ) {
    41         if( sum[k] + pd > maxl ) maxl = sum[k] + pd, wh = pos[k];
    42         return;
    43     }
    44     if( ql <= mid ) querymx(lc,l,mid,pd+v[k]);
    45     if( qr > mid ) querymx(rc,mid+1,r,pd+v[k]);
    46 }
    47  
    48 inline void out(int k,int l,int r,ll pd) {
    49     if( l == r ) { cout<<pd+sum[k]<<" "; return; }
    50     out(lc,l,mid,pd+v[k]); out(rc,mid+1,r,pd+v[k]);
    51 }
    52  
    53 map<int,int> last; int pre[maxn], val[maxn];
    54 struct node{ int l, r, id, pos; ll v; bool operator < (const node&rhs) const { return v < rhs.v; }; };
    55 priority_queue<node> q; 
    56 #define mkp(i,j,k,l,d) (node){i,j,k,l,d} 
    57 int main() {
    58     int n = read(), k = read();
    59     rep(i,1,n) val[i] = read(), pre[i] = last[val[i]], last[val[i]] = i;;
    60     build(1,n,rot[0]);
    61     rep(i,1,n) {
    62         ql = pre[i] + 1, qr = i, d = val[i];
    63         update(rot[i],rot[i-1],1,n);
    64         ql = 1, qr = i; maxl = -inf;
    65         querymx(rot[i],1,n,0); 
    66         //out(rot[i],1,n,0); cout<<endl;
    67         q.push(mkp(1,i,i,wh,maxl));
    68     }
    69     rep(i,1,k-1) {
    70         node a = q.top(); q.pop();
    71         int l = a.l, r = a.r, at = a.pos, id = a.id;
    72         if( l < at ) {
    73             ql = l, qr = at - 1; maxl = -inf; querymx(rot[id],1,n,0);
    74             q.push(mkp(ql,qr,id,wh,maxl));
    75         } 
    76         if( at < r ) {
    77             ql = at + 1, qr = r; maxl = -inf; querymx(rot[id],1,n,0);
    78             q.push(mkp(ql,qr,id,wh,maxl));
    79         }
    80     }
    81     node a = q.top();
    82     printf("%lld
    ", a.v);
    83     return 0;
    84 }
    85 
  • 相关阅读:
    Adobe Edge Animate –EdgeCommons Log和全局变量设置功能
    Adobe Edge Animate –使用EdgeCommons加载和播放音频
    Adobe Edge Animate –svg地图交互-精确的边缘及颜色置换
    Adobe Edge Animate –解决图形边缘精确检测问题-通过jquery加载svg图片
    Adobe Edge Animate –修改Edge Commons Spotlight功能,使之能支持播放中国网站视频
    Adobe Edge Animate –获取鼠标位置及跟随鼠标功能实现
    Adobe Edge Animate –使用css制作菜单
    Adobe Edge Animate –Edge Commons强势来袭,Edge团队开发成为现实
    Adobe Edge Animate –可重复使用的个性化按钮制作
    Adobe Edge Animate –弹性的方块-使用tweenmax缓动效果
  • 原文地址:https://www.cnblogs.com/83131yyl/p/5463388.html
Copyright © 2011-2022 走看看