HDU 4638 多校四-1007

来源:互联网 发布:python pdb模块 编辑:程序博客网 时间:2024/05/21 10:24

题目:题目链接

这道题目的意思是给你一个序列,在给你N个区间,问你一段区间里的数能组成多少段连续的数。

分析:

  概述出来其实就是加入一个数字a之后,检查一下有没有a-1和a+1已经存在。存在的话就在updata里面减一。如果说

是存在其中之一,就继续添加。两者都木有的话,就段数加1.设v[i]为加入第i个数后的改变量,那么加到第x数时的段

数就是sum{v[i]}(1<=i<=x}。若删除某个数,那么这个数两端的数的改变量也会跟着改变,这样一段区间的数构成的段

数就还是他们的v值的和。将询问离线处理,按左端点排序后扫描一遍,左边删除,右边插入,查询就是求区间和。

树状数组更新:


#include <iostream>#include <cstdio>#include <string>#include <string.h>#include <map>#include <vector>#include <cstdlib>#include <algorithm>#include <cmath>#include <queue>#include <set>#include <stack>#include <assert.h>#include <limits.h>#include <wchar.h>#include <complex>#include <deque>#include <functional>#include <list>#include <ios>#include <iosfwd>#include <istream>#include <streambuf>#include <utility>#include <complex.h>#include <inttypes.h>#define N 100005using namespace std;int AC[N];struct node{    int st;    int ed;    int num;} que[N];int P[N];int SP[N];int ANS[N];int n, m, t;bool cmp(node a, node b){    return a.ed < b.ed;}int lowbit(int i){    return i&-i;}void updata(int k,int val){    for(int i = k; i <= n; i += lowbit(i))        SP[i] += val;}int fun(int k){    int s = 0;    for(int i = k; i > 0; i -= lowbit(i))        s += SP[i];    return s;}int main(){    scanf("%d", &t);    while(t--)    {        memset(SP, 0, sizeof(SP));        scanf("%d%d", &n, &m);        for(int i = 1; i <= n; ++i)        {            scanf("%d", &AC[i]);            P[AC[i]] = i;        }        for(int i = 1; i <= m; ++i)        {            scanf("%d%d", &que[i].st, &que[i].ed);            que[i].num = i;        }        sort(que+1, que+m+1, cmp);        int j = 1;        for(int i = 1; i <= n; ++i)        {            updata(i, 1);            if(AC[i] > 1 && P[AC[i]-1] < i)                updata(P[AC[i]-1], -1);            if(AC[i] < n && P[AC[i]+1] < i)                updata(P[AC[i]+1], -1);            while(i == que[j].ed && j <= m)            {                ANS[que[j].num] = fun(que[j].ed) - fun(que[j].st-1);                j++;            }        }        for(int i = 1; i <= m; ++i)            printf("%d\n", ANS[i]);    }    return 0;}

努力努力...