poj 2352 Stars (线段树#4/树状数组)

来源:互联网 发布:字符串数组 strstr 编辑:程序博客网 时间:2024/05/01 17:29

本质上是维护一个表,每次改变一个元素的值,然后求前i个元素的和。

法一:线段树

      我本来是想每个叶节点表示从1到该节点位置的元素和,插入一个元素,那么它后面的节点的值都要加一,这便是操作区间。可是我这样是复杂化了,无限WA。

     其实就是简单的求和问题,每个节点维护一个sum值就好了。

   代码:454ms

   

#include <cstdio>#include <cstring>using namespace std;#define N 15009 #define L 32010 struct node{       int l, r;       int val;    }Tree[L * 5];///int n;int level[N];void build(int l, int r, int x){     Tree[x].l = l;     Tree[x].r = r;     Tree[x].val = 0;     if (l == r)return;     int mid = (l + r) / 2;     build(l, mid, x * 2);     build(mid + 1, r, x * 2 + 1);}void update(int nu,  int x){       if (Tree[x].l <= nu && nu <= Tree[x].r)       {                Tree[x].val++;        }       if (Tree[x].l == Tree[x].r)return;        int mid = (Tree[x].l + Tree[x].r) / 2;       if (mid < nu)update(nu, x * 2 + 1);       else if (mid >= nu)update(nu,  x * 2);} int find(int l, int r,  int x){        if (Tree[x].l == l && Tree[x].r == r)       {                     return Tree[x].val;       }       int mid =  (Tree[x].l + Tree[x].r) / 2;       if (mid < l)return find(l, r, x * 2 + 1);       if (mid >= r)return find(l, r, x * 2);       return find(l, mid, x * 2) + find(mid + 1, r, x * 2 + 1); }    int main(){   // FILE* fp = fopen("in.txt", "r");     scanf(  "%d", &n);     build(0, L, 1);    for (int i = 0; i < n; i++) level[i] = 0;    int x, y;     for (int i = 0; i < n; i++)    {          scanf( "%d %d", &x, &y);          level[find(0, x, 1)]++;          update(x, 1);     }    for (int i = 0; i < n; i++)         printf("%d\n", level[i]);   //  getchar();    return 0;} 



法二:树状数组

       树状数组应用范围较窄,“改变一个元素,求前i个元素的和”。

     391ms

   

#include <cstdio>#include <cstdlib>#include <cstring> using namespace std;#define N 32010    int n, c[N], level[N];inline int lowbit(int x){      return x & (-x);}int sum(int x){     int ans = 0;     while (x > 0)     {           ans += c[x];           x -= lowbit(x);     }      return ans;} void update(int i){     while (i <= N)     {           c[i] ++;           i += lowbit(i);     } } int main(){      int x, y;      scanf("%d", &n);      memset(c, 0, sizeof(c));      memset(level, 0, sizeof(level));       for (int i = 0; i < n; i++)      {            scanf("%d %d", &x, &y);            level[sum(x + 1)]++;            update(x + 1);      }      for (int i = 0; i < n; i++)printf("%d\n", level[i]);     // scanf("%d", &n);       return 0;} 


原创粉丝点击