zoukankan      html  css  js  c++  java
  • poj 3368

    求一段非递减序列出现频率最高的数字的个数,线段树做的,每个节点记录5个信息

    lv:区间最左边的数字,rv:区间最右边的数字

    ml:与区间最左边的数字相等的数字的个数,mr:与区间最右边的数字相等的数字的个数

    maxv:区间中出现频率最高的数字的个数,然后通过线段树查询即可

    以后看到与区间信息有关的题目要想到用线段树

     1 #include <iostream>
     2     #include <cstdio>
     3     using namespace std;
     4     const int maxn=100000+10;
     5     struct node
     6     {
     7         int ml,mr,maxv,lv,rv;
     8     };
     9     node sgtree[maxn*3];
    10     int a[maxn];
    11     int n,q,tot,k;
    12     int ql,qr;
    13     void Init(int no,int l,int r)
    14     {
    15         if(l==r)
    16         {
    17             sgtree[no].maxv=1;
    18             sgtree[no].ml=1;
    19             sgtree[no].mr=1;
    20             sgtree[no].lv=a[tot];
    21             sgtree[no].rv=a[tot++];
    22             return;
    23         }
    24         int mid=l+(r-l)/2;
    25         int tl=no*2+1,tr=no*2+2;
    26         Init(tl,l,mid);
    27         Init(tr,mid+1,r);
    28         sgtree[no].maxv=max(sgtree[tl].maxv,sgtree[tr].maxv);
    29         if(sgtree[tl].rv==sgtree[tr].lv)
    30             sgtree[no].maxv=max(sgtree[no].maxv,sgtree[tl].mr+sgtree[tr].ml);
    31         sgtree[no].lv=sgtree[tl].lv;
    32         sgtree[no].rv=sgtree[tr].rv;
    33        sgtree[no].ml=sgtree[tl].ml;
    34         sgtree[no].mr=sgtree[tr].mr;
    35         if(sgtree[tl].lv==sgtree[tr].lv) sgtree[no].ml+=sgtree[tr].ml;
    36         if(sgtree[tr].rv==sgtree[tl].rv) sgtree[no].mr+=sgtree[tl].mr;
    37     }
    38     int Query(int no,int l,int r)
    39     {
    40         int tl=no*2+1,tr=no*2+2;
    41         if(l>=ql&&r<=qr) return sgtree[no].maxv;
    42         int mid=l+(r-l)/2;
    43         if(ql>mid) return Query(no*2+2,mid+1,r);
    44         else if(qr<=mid) return Query(no*2+1,l,mid);
    45         else
    46         {
    47             int t1=Query(tl,l,mid);
    48             int t2=Query(tr,mid+1,r);
    49             int ans=max(t1,t2);
    50             if(sgtree[tl].rv==sgtree[tr].lv)
    51             {
    52             int a1=(mid-ql+1)>=sgtree[tl].mr?sgtree[tl].mr:(mid-ql+1);
    53             int a2=(qr-mid)>=sgtree[tr].ml?sgtree[tr].ml:(qr-mid);
    54             ans=max(ans,a1+a2);
    55             }
    56             return ans;
    57         }
    58     }
    59     int main()
    60     {
    61         while(scanf("%d",&n)&&n)
    62         {
    63             scanf("%d",&k);
    64             int i;
    65             for(i=0;i<n;i++) scanf("%d",&a[i]);
    66             tot=0;
    67             Init(0,1,n);
    68             int l,r;
    69             int ans;
    70             for(i=0;i<k;i++)
    71             {
    72                 scanf("%d%d",&ql,&qr);
    73                ans=Query(0,1,n);
    74                printf("%d\n",ans);
    75             }
    76         }
    77         return 0;
    78     }
  • 相关阅读:
    Linux系统性能优化
    Linux内核模块
    Linux守护进程的启动方法
    已有的游戏如何快速稳定迁移到云上?
    项目重构--使用策略模式
    设计模式学习--装饰者模式(Decorator Pattern)
    C#/ASP.NET应用程序配置文件app.config/web.config的增、删、改操作
    Resharper上手指南
    ReSharper 配置及用法(转)
    使用线程新建WPF窗体(公用进度条窗体)
  • 原文地址:https://www.cnblogs.com/lj030/p/3083694.html
Copyright © 2011-2022 走看看