zoukankan      html  css  js  c++  java
  • 数据结构(主席树):COGS 2213. K个串

    2213. K个串

    ★★★★   输入文件:bzoj_4504.in   输出文件:bzoj_4504.out   简单对比
    时间限制:20 s   内存限制:512 MB

    【题目描述】

    兔子们在玩k个串的游戏。首先,它们拿出了一个长度为n的数字序列,选出其中的一
    个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次)。
    兔子们想知道,在这个数字序列所有连续的子串中,按照以上方式统计其所有数字之和,第
    k大的和是多少。
     

    【输入格式】

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

    【输出格式】

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

    【样例输入】

    7 5

    3 -2 1 2 2 1 3 -2

    【样例输出】

     4

    【提示】

    1 <= n <= 100000, 1 <= k <= 200000, 0 <= |a_i| <= 10^9数据保证存在第 k 大的和

      

      和HDU 5654 xiaoxin and his watermelon candy几乎一模一样。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <queue>
      6 using namespace std;
      7 const int maxn=100010;
      8 const int INF=23333333;
      9 int hash[maxn],a[maxn],n,k;
     10 int head[maxn],nxt[maxn],pre[maxn];
     11 int rt[maxn],pos[maxn<<6];
     12 int ch[maxn<<6][2],cnt;
     13 long long lx[maxn<<6],tr[maxn<<6];
     14 void Push_up(int x){
     15     int l=ch[x][0],r=ch[x][1];
     16     tr[x]=tr[l]+tr[r];
     17     if(lx[l]>tr[l]+lx[r]){
     18         lx[x]=lx[l];
     19         pos[x]=pos[l];
     20     }
     21     else{
     22         lx[x]=tr[l]+lx[r];
     23         pos[x]=pos[r];
     24     }
     25 }
     26 void Build(int &rt,int l,int r){
     27     rt=++cnt;
     28     if(l==r){
     29         pos[rt]=l;
     30         if(!pre[l]){
     31             tr[rt]=hash[a[l]];
     32             lx[rt]=hash[a[l]];
     33         }
     34         return;
     35     }
     36     int mid=(l+r)>>1;
     37     Build(ch[rt][0],l,mid);
     38     Build(ch[rt][1],mid+1,r);
     39     Push_up(rt);
     40 }
     41 
     42 void Update(int pr,int &rt,int l,int r,int g,int d){
     43     rt=++cnt;
     44     tr[rt]=tr[pr]+d;
     45     if(l==r){
     46         pos[rt]=g;    
     47         lx[rt]=tr[rt];
     48         return;
     49     }
     50     ch[rt][0]=ch[pr][0];
     51     ch[rt][1]=ch[pr][1];
     52     int mid=(l+r)>>1;
     53     if(g<=mid)Update(ch[pr][0],ch[rt][0],l,mid,g,d);
     54     else Update(ch[pr][1],ch[rt][1],mid+1,r,g,d);
     55     Push_up(rt);
     56 }
     57 struct data{int x;long long y;};
     58 data Query(int t,int l,int r,int x,int y)
     59 {
     60     if(l==x && r==y) return (data){pos[t],lx[t]};
     61     int mid=(l+r)>>1;
     62     if(y<=mid) return Query(ch[t][0],l,mid,x,y);
     63     else if(x>mid){
     64         data tmp=Query(ch[t][1],mid+1,r,x,y);
     65         return (data){tmp.x,tmp.y+tr[ch[t][0]]};
     66     }
     67     else{
     68         data tmp1=Query(ch[t][0],l,mid,x,mid);
     69         data tmp2=Query(ch[t][1],mid+1,r,mid+1,y);
     70         if(tmp1.y>tmp2.y+tr[ch[t][0]]) return tmp1;
     71         else return (data){tmp2.x,tmp2.y+tr[ch[t][0]]};
     72     }
     73 }
     74 
     75 struct node{int i,l,r,x; long long y;};
     76 bool operator<(const node& a1,const node& a2)
     77 {return a1.y<a2.y;}
     78 priority_queue<node> q;
     79 
     80 int main(){
     81     freopen("bzoj_4504.in","r",stdin);
     82     freopen("bzoj_4504.out","w",stdout);
     83     scanf("%d%d",&n,&k);
     84     for(int i=1;i<=n;i++)
     85         scanf("%d",&a[i]);
     86     for(int i=1;i<=n;i++)
     87         hash[i]=a[i];
     88     sort(hash+1,hash+n+1);
     89     for(int i=1;i<=n;i++)
     90         a[i]=lower_bound(hash+1,hash+n+1,a[i])-hash;
     91     for(int i=1;i<=n;i++){
     92         pre[i]=head[a[i]];
     93         nxt[head[a[i]]]=i;
     94         head[a[i]]=i;
     95     }
     96     Build(rt[1],1,n);
     97     for(int i=1;i<n;i++){
     98         Update(rt[i],rt[i+1],1,n,i+1,-hash[a[i]]);
     99         if(nxt[i])Update(rt[i+1],rt[i+1],1,n,nxt[i],hash[a[i]]);
    100     }
    101     for(int i=1;i<=n;i++){
    102         data tmp=Query(rt[i],1,n,i,n);
    103         q.push((node){i,i,n,tmp.x,tmp.y});
    104     }
    105     long long ans;
    106     for(int i=1;i<=k;i++){
    107         node t=q.top(); q.pop(); ans=t.y;
    108         if(t.l!=t.x){
    109             data tmp=Query(rt[t.i],1,n,t.l,t.x-1);
    110             q.push((node){t.i,t.l,t.x-1,tmp.x,tmp.y});
    111         }
    112         if(t.r!=t.x){
    113             data tmp=Query(rt[t.i],1,n,t.x+1,t.r);
    114             q.push((node){t.i,t.x+1,t.r,tmp.x,tmp.y});
    115         }
    116     }
    117     printf("%lld
    ",ans);
    118     return 0;
    119 }

      有时间一定要重打!!!

    尽最大的努力,做最好的自己!
  • 相关阅读:
    [转]C#、VB.NET使用HttpWebRequest访问https地址(SSL)的实现
    C#设置System.Net.ServicePointManager.DefaultConnectionLimit,突破Http协议的并发连接数限制
    [转]WebBrowser控件禁用超链接转向、脚本错误提示、默认右键菜单和快捷键
    [转]C#打印DataGridView的例子源码
    c# TreeView 父节点选中/不选时子节点都同步选中/不选
    C#中PictureBox异步加载图片
    [转]FusionCharts 3.1 破解版 – 非常好用的Flash图表控件
    配合JavaScript拖动页面中控件
    在ThinkPad T400上安装win2003 所遇问题
    C# 抛弃MoveTo来实现文件重命名
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5380575.html
Copyright © 2011-2022 走看看