• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
scorpiorax
博客园    首页    新随笔    联系   管理    订阅  订阅
vijos1448校门外的树

描述

校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……
如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:
K=1,K=1,读入l、r表示在区间[l,r]中种上一种树,每次操作种的树的种类都不同
K=2,读入l,r表示询问l~r之间能见到多少种树
(l,r>0)

格式

输入格式

第一行n,m表示道路总长为n,共有m个操作
接下来m行为m个操作

输出格式

对于每个k=2输出一个答案

样例1

样例输入1

5 4
1 1 3
2 2 5
1 2 4
2 3 5
Copy

样例输出1

1
2
Copy

限制

1s

提示

范围:20%的数据保证,n,m<=100
60%的数据保证,n <=1000,m<=50000
100%的数据保证,n,m<=50000

来源

dejiyu@CSC WorkGroup

*******这道题也是树状数组,把每一次种树的开端记为“(”末端记为")",那么一个区间内种树的范围是r前面的“(”和减去前面的“(”个数。用树状数组来记录他们的个数。

本还想用区间修改和区间求和来做这道题,其实并不可做,因为这道题是求种类而不是数目。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 int n,m,i,j,k,l,r,a[50005],b[50005];
 7 int lowbit(int x)
 8 {
 9     return x & (-x);
10 }
11 void add1(int p,int x)
12 {
13     while(p <= n)
14     {
15         a[p] += x;
16         p += lowbit(p);
17     }
18  } 
19 void add2(int p,int x)
20 {
21     while(p <= n)
22     {
23         b[p] += x;
24         p += lowbit(p);
25     }
26 }
27 int chaxun(int p)
28 {
29     int res = 0;
30     while(p > 0)
31     {
32         res += a[p];
33         p -= lowbit(p);
34     }
35     return res;
36 }
37 int chaxun2(int p)
38 {
39     int res = 0;
40     while(p > 0)
41     {
42         res += b[p];
43         p -= lowbit(p);
44     } 
45     return res;
46 }
47 int main()
48 {
49     scanf("%d %d",&n,&m);
50     for(i = 1;i <= m;i++)
51     {
52         scanf("%d %d %d",&k,&l,&r);
53         if(k == 1)
54         {
55             add1(l,1);
56             add2(r,1);
57         }
58         else 
59         printf("%d\n",chaxun(r) - chaxun2(l - 1));
60     }
61     return 0;
62 }

 

posted on 2018-08-07 14:39  scorpiorax  阅读(190)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3