zoukankan      html  css  js  c++  java
  • Super Mario(线段树离线区间k值)

    以前见过这题,没做出来,知道是离线处理,这次仔细想了下,

    首先把出现的高度都map离散化一下,以离散化出来的数目g建树,把每个位置都开俩个vector,一个存以这个位置为L的询问,一个存以这个位置为R的询问。

    然后从1-g 进行更新,假如当前i是以第j个区间的开始位置,那么这时就可以询问一下<=p[j].h的个数s,显然这时第J个区间多加的,需要减掉,p[j].sum-=s;

    然后更新第i个数,update(a[i],1,g,1);再找到某第k区间是以i结尾的,那么依旧询问一下,得出s,p[k].sum+=s;这样就是最终结果。

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<vector>
      7 #include<cmath>
      8 #include<queue>
      9 #include<set>
     10 #include<map>
     11 using namespace std;
     12 #define N 200010
     13 #define LL long long
     14 #define INF 0xfffffff
     15 const double eps = 1e-8;
     16 const double pi = acos(-1.0);
     17 const double inf = ~0u>>2;
     18 int s[N<<2],a[N],b[N];
     19 map<int,int>f;
     20 vector<int>st[N];
     21 vector<int>ed[N];
     22 struct node
     23 {
     24     int l,r,h;
     25     int sum;
     26 }p[N];
     27 bool cmp(node a,node b)
     28 {
     29     if(a.l==b.l)
     30     return a.r<b.r;
     31     return a.l==b.l;
     32 }
     33 void up(int w)
     34 {
     35     s[w] = s[w<<1]+s[w<<1|1];
     36 }
     37 void build(int l,int r,int w)
     38 {
     39     if(l==r)
     40     {
     41         s[w] = 0;
     42         return ;
     43     }
     44     int m = (l+r)>>1;
     45     build(l,m,w<<1);
     46     build(m+1,r,w<<1|1);
     47     up(w);
     48 }
     49 void update(int p,int l,int r,int w)
     50 {
     51     if(l==r)
     52     {
     53         s[w] += 1;
     54         return ;
     55     }
     56     int m = (l+r)>>1;
     57     if(p<=m)
     58     update(p,l,m,w<<1);
     59     else
     60     update(p,m+1,r,w<<1|1);
     61     up(w);
     62 }
     63 int query(int a,int b,int l,int r,int w)
     64 {
     65     if(a<=l&&b>=r)
     66     {
     67         return s[w];
     68     }
     69     int m = (l+r)>>1;
     70     int res =0;
     71     if(a<=m)
     72     res+=query(a,b,l,m,w<<1);
     73     if(b>m)
     74     res+=query(a,b,m+1,r,w<<1|1);
     75     return res;
     76 }
     77 int main()
     78 {
     79     int t,n,q,i,j;
     80     int kk = 0;
     81     scanf("%d",&t);
     82     while(t--)
     83     {
     84         int g = 0;
     85         scanf("%d%d",&n,&q);
     86         f.clear();
     87         for(i = 1; i <= n; i++)
     88         {
     89             scanf("%d",&a[i]);
     90             b[i] = a[i];
     91             st[i].clear();
     92             ed[i].clear();
     93         }
     94         for(i =1;i <= q ;i++)
     95         {
     96             scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].h);
     97             p[i].l++,p[i].r++;
     98             p[i].sum = 0;
     99             st[p[i].l].push_back(i);
    100             ed[p[i].r].push_back(i);
    101             a[n+i] = p[i].h;
    102         }
    103         sort(a,a+n+q+1);
    104         f[a[1]] = ++g;
    105         for(i = 2; i <= n+q ; i++)
    106         {
    107             if(a[i]!=a[i-1])
    108             f[a[i]] = ++g;
    109         }
    110         build(1,g,1);
    111         for(i = 1; i <= n ;i++)
    112         {
    113             if(st[i].size()!=0)
    114             {
    115                 for(j = 0 ;j < st[i].size() ; j++)
    116                 {
    117                     int v = st[i][j];
    118                     int pre = query(1,f[p[v].h],1,g,1);
    119                     p[v].sum -= pre;
    120                 }
    121             }
    122             update(f[b[i]],1,g,1);
    123             if(ed[i].size())
    124             {
    125                 for(j = 0; j < ed[i].size() ;j++)
    126                 {
    127                     int v= ed[i][j];
    128                     int bef = query(1,f[p[v].h],1,g,1);
    129                     p[v].sum+=bef;
    130                 }
    131             }
    132         }
    133         printf("Case %d:
    ",++kk);
    134         for(i = 1; i <= q ; i++)
    135         {
    136             printf("%d
    ",p[i].sum);
    137         }
    138     }
    139     return 0;
    140 }
    View Code
  • 相关阅读:
    取消Git每次拉取、提交推送都要输入密码
    input输入框的oninput和onchange事件
    NPM学习笔记
    命令行语法格式中常用符号的含义
    npm卸载模块报错
    软件的Alpha、Beta、GM、OEM、LTS等版本的含义(转)
    MySQL常用指令
    Git常用指令
    .net Core 解决Form value count limit 1024 exceeded. (文件上传过大)
    EF Core 迁移整理
  • 原文地址:https://www.cnblogs.com/shangyu/p/3759365.html
Copyright © 2011-2022 走看看