区间修改点查询 HDU1556

  1 #include <iostream>
  2 #include <cstdio>
  3 
  4 using namespace std;
  5 
  6 struct Node
  7 {
  8     int l,r;
  9     int v;
 10     int lz;
 11 }bn[400000];
 12 
 13 void build(int k,int l,int r)
 14 {
 15     bn[k].l=l;
 16     bn[k].r=r;
 17     bn[k].lz=0;
 18     if(bn[k].l==bn[k].r)
 19     {
 20         bn[k].v=0;
 21         return ;
 22     }
 23     int lk=k*2;
 24     int rk=lk+1;
 25     int mid=(l+r)/2;
 26     build(lk,l,mid);
 27     build(rk,mid+1,r);
 28     bn[k].v=0;
 29 }
 30 
 31 void push(int k)
 32 {
 33     int lk=k*2;
 34     int rk=lk+1;
 35     bn[lk].v+=bn[k].lz;
 36     bn[rk].v+=bn[k].lz;
 37     bn[lk].lz+=bn[k].lz;
 38     bn[rk].lz+=bn[k].lz;
 39     bn[k].lz=0;
 40 }
 41 
 42 void change(int k,int l,int r)
 43 {
 44     if(bn[k].l==l&&bn[k].r==r)
 45     {
 46         bn[k].lz++;
 47         bn[k].v=bn[k].lz*(bn[k].r-bn[k].l+1);
 48         return ;
 49     }
 50     if(bn[k].lz)
 51         push(k);
 52     int lk=k*2;
 53     int rk=lk+1;
 54     if(bn[lk].r>=r)
 55         change(lk,l,r);
 56     else if(bn[rk].l<=l)
 57         change(rk,l,r);
 58     else
 59     {
 60         change(lk,l,bn[lk].r);
 61         change(rk,bn[rk].l,r);
 62     }
 63     bn[k].v=bn[rk].v+bn[lk].v;
 64 }
 65 
 66 int ans;
 67 void search(int k,int i)
 68 {
 69     if(bn[k].l==i&&bn[k].r==i)
 70     {
 71         ans=bn[k].v;
 72         return ;
 73     }
 74     if(bn[k].lz)
 75         push(k);
 76     int lk=k*2;
 77     int rk=lk+1;
 78     if(bn[lk].r>=i)
 79         search(lk,i);
 80     else if(bn[rk].l<=i)
 81         search(rk,i);
 82     bn[k].v=bn[rk].v+bn[lk].v;
 83 }
 84 
 85 int main()
 86 {
 87     int n;
 88     while(cin>>n&&n)
 89     {
 90         int a,b;
 91         build(1,1,n);
 92         for(int i=1;i<=n;i++)
 93         {
 94             scanf("%d%d",&a,&b);
 95             change(1,a,b);
 96         }
 97         search(1,1);
 98         cout<<ans;
 99         for(int i=2;i<=n;i++)
100         {
101             search(1,i);
102             cout<<" "<<ans;
103         }
104         cout<<endl;
105     }
106     return 0;
107 }
View Code

这是正常线段树做法

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 
 7 int an[100010];
 8 int ans[100010];
 9 
10 int main()
11 {
12     int n;
13     while(cin>>n&&n)
14     {
15         memset(an,0,sizeof(an));
16         memset(ans,0,sizeof(ans));
17         int a,b;
18         for(int i=1;i<=n;i++)
19         {
20             scanf("%d%d",&a,&b);
21             an[a]+=1;
22             an[b+1]+=-1;
23         }
24         for(int i=1;i<=n;i++)
25         {
26             ans[i]=ans[i-1]+an[i];
27         }
28         cout<<ans[1];
29         for(int i=2;i<=n;i++)
30         {
31             cout<<" "<<ans[i];
32         }
33         cout<<endl;
34     }
35     return 0;
36 }
View Code

简便方法,时间复杂度为N

原文地址:https://www.cnblogs.com/wsruning/p/4691416.html