LOJ10115

解题思路:开始怎么想都不知道怎么维护不同段中树的种类是否相同的情况,感觉这题有个思维技巧还是挺难想的,就是我们要开两个数组,sum1分别维护左端点的数目,另一个数组sum2维护右端点的数目。这样区间[l,r]的树的种类的数目就是1-r中左端点的数目减去1-(l-1)中右端点的数目,即表示为sum1[r]-sum2[l-1]。

如图假如我们第一次在区间a[2,6]种上一种树,然后再在区间b[5,10]种上一种树,这时我们要统计区间c[8,12]中树的种类数目,我们就统计[1,12]中左端点的数目即 sum1[12]等于2,说明有两种树可能在给定区间内,然后我们再求区间[1,7]中右端点的数目即sum2[7]-sum2[1]=1,表示有一种树完全在给定区间左边,并不是我们要求的,所以减去就好了,所以答案就为sum1[12]-(sum2[7]-sum2[1])=1了。

原解析地址:https://www.cnblogs.com/zjl192628928/p/10630450.html

 1 #include<iostream>
 2 using namespace std;
 3 #define lowbit(i) i&(-i)
 4 int sum1[100100],sum2[100100];
 5 int n,m;
 6 
 7 void up1(int x,int val){
 8     while (x<=n){
 9         sum1[x]+=val;
10         x+=lowbit(x);
11     } 
12 }
13 
14 void up2(int x,int val){
15     while (x<=n){
16         sum2[x]+=val;
17         x+=lowbit(x);
18     }
19 }
20 
21 int q1(int x){
22     int ret=0;
23     while (x){
24         ret+=sum1[x];
25         x-=lowbit(x);
26     }
27     return ret;
28 }
29 
30 int q2(int x){
31     int ret=0;
32     while (x){
33         ret+=sum2[x];
34         x-=lowbit(x);
35     }
36     return ret;
37 }
38 
39 int main(){
40     cin>>n>>m;
41     while (m--){
42         int k,l,r;
43         cin>>k>>l>>r;
44         if (k==1){
45             up1(l,1);
46             up2(r,1);
47         }
48         else{
49             cout<<q1(r)-q2(l-1)<<endl;
50         }
51     }
52     return 0;
53 }

猜你喜欢

转载自www.cnblogs.com/whiteli/p/12966225.html
今日推荐