zoukankan      html  css  js  c++  java
  • bzoj4504 k个串 kstring 可持久化线段树 (标记永久化)

    【fjwc2015】k个串 kstring

    【题目描述】

    兔子们在玩k个串的游戏。首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次)。

    兔子们想知道,在这个数字序列所有连续的子串中,按照以上方式统计其所有数字之和,第k大的和是多少。

    【输入格式】

    第一行,两个整数n和k,分别表示长度为n的数字序列和想要统计的第k大的和

    接下里一行n个数a_i,表示这个数字序列

    【输出格式】

    一行一个整数,表示第k大的和

    【样例输入】

    7 5

    3 -2 1 2 2 1 3 -2

    【样例输出】

    4

    【数据范围】

    对于20%的数据,1 <= n <= 2000

    对于另外20%的数据,0 <= a_i <= 10^9

    对于100%的数据,1 <= n <= 100000, 1 <= k <= 200000, 0 <= |a_i| <= 10^9

    数据保证存在第k大的和

    题解:

      理解要紧,很简单的。

      一开始以为没有地方可以提交,结果发现bzoj上就有,

      可以rt[i]表示以i为左端点的区间。

      nxt[i]表示a[i]下一次出现的位置。

      发现rt[i]对于rt[i-1],发现就是在i-----nxt[i]-1这些位置都减去a[i],

      然后,然后对于i这个位置需要变为-inf,因为无法取到。

      然后先建辅助树rt[0],即永久性flag标记打上去的区间修改,然后再以-inf,那个位置再建出

      rt[i]即可,然后进行k次操作,用堆来维护即可。

      1 #include<cstring>
      2 #include<cmath>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cstdio>
      6 #include<map>
      7 #include<queue>
      8 
      9 #define lson tr[p].ls
     10 #define rson tr[p].rs
     11 #define N 100007
     12 #define ll long long
     13 using namespace std;
     14 const ll inf=2000000000000007;
     15 inline ll read()
     16 {
     17     ll x=0,f=1;char ch=getchar();
     18     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     19     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     20     return x*f;
     21 }
     22 
     23 ll n,k,sz;
     24 ll a[N],id[N],b[N],rt[N*3],nxt[N];
     25 map<ll,ll>p;
     26 struct Node
     27 {
     28     ll ls,rs,mx,flag,tag;
     29 }tr[N*100];
     30 struct Date
     31 {
     32     ll num,wei,rt;
     33     friend bool operator < (Date x,Date y)
     34     {
     35         return x.num<y.num;
     36     }
     37 };
     38 priority_queue<Date>q;
     39 
     40 bool cmp(ll x,ll y)
     41 {
     42     if (a[x]==a[y]) return x<y;
     43     else return a[x]<a[y];
     44 }
     45 inline void update(ll p)
     46 {
     47     if (tr[lson].mx+tr[lson].tag>tr[rson].mx+tr[rson].tag) tr[p].mx=tr[lson].mx+tr[lson].tag,tr[p].flag=tr[lson].flag;
     48     else tr[p].mx=tr[rson].mx+tr[rson].tag,tr[p].flag=tr[rson].flag;
     49 }
     50 void build(ll &p,ll l,ll r)
     51 {
     52     p=++sz;
     53     if (l==r)
     54     {
     55         tr[p].mx=b[l];
     56         tr[p].flag=l;
     57         return;
     58     }
     59     ll mid=(l+r)>>1;
     60     build(tr[p].ls,l,mid),build(tr[p].rs,mid+1,r);
     61     update(p);
     62 }
     63 void build_new(ll yl,ll &xz,ll l,ll r,ll x,ll y,ll z)
     64 {
     65     xz=++sz,tr[xz]=tr[yl];
     66     if (l==x&&r==y)
     67     {
     68         tr[xz].tag+=z;
     69         return;
     70     }
     71     //标记永久化。 
     72     ll mid=(l+r)>>1;
     73     if (y<=mid) build_new(tr[yl].ls,tr[xz].ls,l,mid,x,y,z);
     74     else if (x>mid) build_new(tr[yl].rs,tr[xz].rs,mid+1,r,x,y,z);
     75     else build_new(tr[yl].ls,tr[xz].ls,l,mid,x,mid,z),build_new(tr[yl].rs,tr[xz].rs,mid+1,r,mid+1,y,z);
     76     update(xz);
     77 }
     78 int main()
     79 {
     80     freopen("kstring.in","r",stdin);
     81     freopen("kstring.out","w",stdout);
     82     
     83     n=read(),k=read();
     84     for (ll i=1;i<=n;i++)
     85         a[i]=read(),id[i]=i;
     86     sort(id+1,id+n+1,cmp);
     87     a[0]=-inf;
     88     for (ll i=1;i<=n;i++)
     89         if (a[id[i]]!=a[id[i-1]]) b[id[i]]=a[id[i]];
     90     for (ll i=1;i<=n;i++) b[i]+=b[i-1];
     91     build(rt[1],1,n);
     92     for (ll i=n;i>=1;i--)
     93     {
     94         if (!p[a[i]]) nxt[i]=n+1;
     95         else nxt[i]=p[a[i]];
     96         p[a[i]]=i;
     97     }
     98     for (ll i=2;i<=n;i++)
     99     {
    100         if (i>nxt[i-1]-1) build_new(rt[i-1],rt[0],1,n,1,n,0);
    101         else build_new(rt[i-1],rt[0],1,n,i,nxt[i-1]-1,-a[i-1]);
    102         build_new(rt[0],rt[i],1,n,i-1,i-1,-inf);
    103     }
    104     for (ll i=1;i<=n;i++)
    105         q.push((Date){tr[rt[i]].mx+tr[rt[i]].tag,tr[rt[i]].flag,i});
    106     for(ll i=1;i<k;i++)
    107     {
    108         Date now=q.top();q.pop();
    109         build_new(rt[now.rt],rt[n+i],1,n,now.wei,now.wei,-inf);
    110         q.push((Date){tr[rt[n+i]].mx,tr[rt[n+i]].flag,i+n});
    111     }
    112     Date now=q.top();
    113     printf("%lld
    ",now.num);
    114 }

      

  • 相关阅读:
    c++ static_cast和dynamic_cast详解
    python 字符串格式化 format
    python zip() 函数
    零零散散的python笔记 2
    PAT 1017
    PAT 1016
    PAT 1015
    Jordan Lecture Note-8: The Sequential Minimal Optimization Algorithm (SMO).
    Jordan Lecture Note-7: Soft Margin SVM
    PAT 1014
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8059631.html
Copyright © 2011-2022 走看看