• Group


    hdu4638:http://acm.hdu.edu.cn/showproblem.php?pid=4638

    题意:找到区间能,有多少组连续数字串 

    题解:离线处理,从开始到1--n开始扫描,用树状数组记录每个位置构成组的情况。对于i位置上的数,一定会构成一个组,所以add(i,1),如果a[i]-1和a[i]+1在之前就已经出现,那么就可以删除了合并。add(pos[a[i]-1],-1),add(pos[a[i]+1],-1),如果有以i为右端点的查询,则该查询就是ans[id]=getsum(r)-getsum(l-1);

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<vector>
     6 using namespace std;
     7 const int N=1e5+19;
     8 int c[N],a[N],ll[N],rr[N],ans[N],pos[N];
     9 bool flag[N];
    10 int n,m;
    11 vector<int>mp[N];
    12 int lowbit(int x){
    13   return x&(-x);
    14 }
    15 
    16 void add(int x,int val){
    17     while(x<=n){
    18         c[x]+=val;
    19         x+=lowbit(x);
    20     }
    21 }
    22 int getsum(int x){
    23     int sum=0;
    24     while(x>0){
    25         sum+=c[x];
    26         x-=lowbit(x);
    27     }
    28    return sum;
    29 }
    30 int main(){
    31    int T;
    32    scanf("%d",&T);
    33    while(T--){
    34        scanf("%d%d",&n,&m);
    35        for(int i=1;i<=n;i++){
    36         scanf("%d",&a[i]);
    37          pos[a[i]]=i;
    38        }
    39 
    40        memset(c,0,sizeof(c));
    41        memset(flag,0,sizeof(flag));
    42         for(int i=1;i<=n;i++)
    43            mp[i].clear();
    44         for(int i=1;i<=m;i++){
    45             scanf("%d%d",&ll[i],&rr[i]);
    46             mp[rr[i]].push_back(i);
    47         }
    48         for(int i=1;i<=n;i++){
    49             int pre=a[i]-1;
    50             int next=a[i]+1;
    51             if(pre>=1&&flag[pre]){
    52                 add(pos[pre],-1);
    53             }
    54             if(next<=n&&flag[next]){
    55                 add(pos[next],-1);
    56             }
    57              add(i,1);
    58             flag[a[i]]=1;
    59             int tt=mp[i].size();
    60            for(int j=0;j<tt;j++){
    61               int v=mp[i][j];
    62               ans[v]=getsum(i)-getsum(ll[v]-1);
    63            }
    64         }
    65          for(int i=1;i<=m;i++)
    66            printf("%d
    ",ans[i]);
    67    }
    68 
    69 }
    View Code
  • 相关阅读:
    C语言 · 新生舞会
    C语言 · 集合运算
    C语言 · 字符串的展开
    C语言 · 学做菜
    C语言 · 最长公共子序列 · 最长字符序列
    C语言 · 复数求和
    C语言 · 扶老奶奶过街
    C语言 · 删除重复元素
    1-3
    1-4
  • 原文地址:https://www.cnblogs.com/chujian123/p/4004164.html
Copyright © 2020-2023  润新知