• 【BZOJ4504&&Hihocoder1046】K个串(主席树,堆)


    题意:一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次)询问第k大的和是多少

    1 <= n <= 100000, 1 <= k <= 200000, 0 <= a[i]<= 10^9

    思路:类似于超级钢琴的思路

    对于每一个右端点建立一棵主席树维护左端点的最大值

    对于a[i]它对[last[a[i]]+1,i]有a[i]的贡献

    再维护一个堆维护全局最大值

    删除的时候就找到最大值的位置赋值成最小值

    C++ STL 不会用 好烦

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<ctime>
      6 #include<cmath>
      7 #include<algorithm>
      8 #include<iomanip>
      9 #include<vector>
     10 #include<map>
     11 #include<set>
     12 #include<bitset>
     13 #include<queue>
     14 #include<stack>
     15 using namespace std;
     16 typedef long long ll;
     17 typedef unsigned int uint;
     18 typedef unsigned long long ull;
     19 typedef pair<int,int> PII;
     20 typedef vector<int> VI;
     21 #define fi first
     22 #define se second
     23 #define MP make_pair
     24 #define N   21000000
     25 #define M   110000
     26 #define eps 1e-8
     27 #define pi  acos(-1)
     28 #define oo  1e18
     29 #define MOD 10007
     30 
     31 struct node
     32 {
     33     ll v;
     34     int id;
     35     node()
     36     {
     37     }
     38     node(ll V,int P)
     39     {
     40         v=V; id=P;
     41     }
     42     friend bool operator <(node x,node y)
     43     {
     44         return x.v<y.v;
     45     }
     46 };
     47 
     48 struct tree
     49 {
     50     int l,r;
     51     ll a,s;
     52 }t[N];
     53 
     54 priority_queue<node>q;
     55 map<int,int>last;
     56 int a[M],root[M],n,cnt;
     57 
     58 void pushup(int p)
     59 {
     60     t[p].s=0;
     61     if(!t[p].r) t[p].s=t[t[p].l].s;
     62      else if(!t[p].l) t[p].s=t[t[p].r].s;
     63       else t[p].s=max(t[t[p].l].s,t[t[p].r].s);
     64     t[p].s+=t[p].a;
     65 }
     66 
     67 void update(int l,int r,int x,int y,int v,int &r1,int r2)
     68 {
     69     r1=++cnt;
     70     t[r1]=t[r2];
     71     if(x<=l&&r<=y)
     72     {
     73         t[r1].a+=v;
     74         pushup(r1);
     75         return;
     76     }
     77     int mid=(l+r)>>1;
     78     if(x<=mid) update(l,mid,x,y,v,t[r1].l,t[r2].l);
     79     if(y>mid) update(mid+1,r,x,y,v,t[r1].r,t[r2].r);
     80     pushup(r1);
     81 }
     82 
     83 void del(int l,int r,int &p)
     84 {
     85     int x=p;
     86     p=++cnt;
     87     t[cnt]=t[x];
     88     if(l==r)
     89     {
     90         t[p].a=-oo;
     91         pushup(p);
     92         return;
     93     }
     94     int mid=(l+r)>>1;
     95     if(!t[p].r) del(l,mid,t[p].l);
     96      else if(!t[p].l) del(mid+1,r,t[p].r);
     97       else
     98       {
     99               if(t[t[p].l].s>=t[t[p].r].s) del(l,mid,t[p].l);
    100                else del(mid+1,r,t[p].r);
    101       }
    102     pushup(p);
    103 }
    104     
    105 
    106 int main()
    107 {
    108     //freopen("bzoj4504.in","r",stdin);
    109     //freopen("bzoj4504.out","w",stdout); 
    110     int k;
    111     scanf("%d%d",&n,&k);
    112     cnt=0;
    113     for(int i=1;i<=n;i++)
    114     {
    115         scanf("%d",&a[i]);
    116         update(1,n,i,i,0,root[i],root[i-1]);
    117         update(1,n,last[a[i]]+1,i,a[i],root[i],root[i]);
    118         last[a[i]]=i;
    119         q.push(node(t[root[i]].s,i));
    120     }
    121     for(int i=1;i<k;i++)
    122     {
    123         int x=q.top().id;
    124         q.pop();
    125         del(1,n,root[x]);
    126         q.push(node(t[root[x]].s,x));
    127     }
    128     printf("%lld
    ",q.top().v);
    129     return 0;
    130 }
    131     
    132     
  • 相关阅读:
    Mysql外键和表关系
    列类型-字符类型
    列类型-日期时间型
    列类型
    破解MySQL的root密码
    数据库简单使用
    数据库简介
    socketserver
    python网络编程-粘包问题的解决
    python-网络编程,简单模型
  • 原文地址:https://www.cnblogs.com/myx12345/p/9873854.html
Copyright © 2020-2023  润新知