【Tyvj】1473校门外的树3 线段树/树状数组

描述

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

输入格式

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

输出格式

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

测试样例1

输入

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

输出


2

备注

范围:20%的数据保证,n,m<=100
      60%的数据保证,n <=1000,m<=50000
      100%的数据保证,n,m<=50000
注意:树是可以重叠的,比如1号位置上可以种多种树

题解

用两个线段树维护每个节点左右端点个数,端点数即是该点上覆盖的线段;

代码

  1 #include <cstdio>
  2 #include <cmath>
  3 #include <cstring>
  4 #include <ctime>
  5 #include <iostream>
  6 #include <algorithm>
  7 #include <set>
  8 #include <vector>
  9 #include <queue>
 10 #include <typeinfo>
 11 #include <map>
 12 #include <stack>
 13 typedef long long ll;
 14 #define inf 0x7fffffff
 15 using namespace std;
 16 inline ll read()
 17 {
 18     ll x=0,f=1;
 19     char ch=getchar();
 20     while(ch<‘0‘||ch>‘9‘)
 21     {
 22         if(ch==‘-‘)f=-1;
 23         ch=getchar();
 24     }
 25     while(ch>=‘0‘&&ch<=‘9‘)
 26     {
 27         x=x*10+ch-‘0‘;
 28         ch=getchar();
 29     }
 30     return x*f;
 31 }
 32 //**************************************************************************************
 33 int n,m;
 34 struct ss
 35 {
 36     int l,r;
 37     int left,right;
 38 } tr[200001];
 39 void build(int k,int s,int t)
 40 {
 41     tr[k].left=s;
 42     tr[k].right=t;
 43     if(s==t)return;
 44     int mid=(s+t)>>1;
 45     build(k<<1,s,mid);
 46     build(k<<1|1,mid+1,t);
 47 }
 48 void insertl(int k,int x,int y)
 49 {
 50     int l=tr[k].left,r=tr[k].right;
 51     if(l==x&&y==r)
 52     {
 53         tr[k].l++;
 54         return;
 55     }
 56     int mid=(l+r)>>1;
 57     if(y<=mid)insertl(k<<1,x,y);
 58     else if(x>mid)insertl(k<<1|1,x,y);
 59     else
 60     {
 61         insertl(k<<1,x,mid);
 62         insertl(k<<1|1,mid+1,y);
 63     }
 64 }
 65 void insertr(int k,int x,int y)
 66 {
 67     int l=tr[k].left,r=tr[k].right;
 68     if(l==x&&y==r)
 69     {
 70         tr[k].r++;
 71         return;
 72     }
 73     int mid=(l+r)>>1;
 74     if(y<=mid)insertr(k<<1,x,y);
 75     else if(x>mid)insertr(k<<1|1,x,y);
 76     else
 77     {
 78         insertr(k<<1,x,mid);
 79         insertr(k<<1|1,mid+1,y);
 80     }
 81 }
 82 int askl(int k,int x)
 83 {
 84     int l=tr[k].left,r=tr[k].right;
 85     if(l==r)return tr[k].l;
 86     int mid=(l+r)>>1;
 87     if(x<=mid)return tr[k].l+askl(k<<1,x);
 88     else return tr[k].l+askl(k<<1|1,x);
 89 }
 90 int askr(int k,int x)
 91 {
 92     int l=tr[k].left,r=tr[k].right;
 93     if(l==r)return tr[k].r;
 94     int mid=(l+r)>>1;
 95     if(x<=mid)return tr[k].r+askr(k<<1,x);
 96     else return tr[k].r+askr(k<<1|1,x);
 97 }
 98 int main()
 99 {
100     int total=0,ans;
101     scanf("%d%d",&n,&m);
102     build(1,0,n);//l最小为1,所以是0到n
103     for(int i=1; i<=m; i++)
104     {
105         int t,a,b;
106         scanf("%d%d%d",&t,&a,&b);
107         if(t==1)
108         {
109             insertl(1,0,a-1);//考虑到a==1
110             insertr(1,b+1,n);
111             total++;
112         }
113         else
114         {
115             ans=askr(1,a)+askl(1,b);
116             printf("%d\n",total-ans);
117         }
118     }
119     return 0;
120 }
时间: 2024-10-14 12:30:43

【Tyvj】1473校门外的树3 线段树/树状数组的相关文章

Tyvj - 1286 - 校门外的树2

描述 Description 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L,都种有一棵树. 由于马路上有一些区域要用来建地铁.这些区域用它们在数轴上的起始点和终止点表示.已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分.现在要把这些区域中的树(包括区域端点处的两棵树)移走.你的任务是计算将这些树都移走后,马路上还有多少棵树. 输入格式 I

TyvjOJ题目 P1473 校门外的树3(线段树区间染色种类数不覆盖)

P1473 校门外的树3 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的-- 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作: K=1,读入l,r表示在l~r之间种上的一种树 K=2,读入l,r表示询问l~r之间能见到多少种树 (l,r>0) 输入格式 第一行n,m表示道路总长为n,共有m个操作 接下来m行为m个操作 输出格式 对于每个k=

回档|校门外的树3|线段树的应用

描述 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作: K=1,读入l,r表示在l~r之间种上的一种树 K=2,读入l,r表示询问l~r之间能见到多少种树 (l,r>0) 输入格式 第一行n,m表示道路总长为n,共有m个操作 接下来m行为m个操作 输出格式 对于每个k=2输出一个答案 备注 范围:20%的数据保证,n,m<=100       60%的数据保证,n <=

Vijos P1448 校门外的树【多解,线段树,树状数组,括号序列法+暴力优化】

校门外的树 描述 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作: 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

Vijos P1103 校门外的树【线段树,模拟】

校门外的树 描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L,都种有一棵树. 由于马路上有一些区域要用来建地铁.这些区域用它们在数轴上的起始点和终止点表示. 已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分.现在要把这些区域中的树(包括区域端点处的两棵树)移走.你的任务是计算将这些树都移走后,马路上还有多少棵树. 格式 输入格式 输入的

线段树 [SWUST OJ 764] 校门外的树 Plus Plus

校门外的树 Plus Plus(0764) Time limit(ms): 1000 Memory limit(kb): 65535 Submission: 214 Accepted: 15 Description 西南某科技大学的校门外长度为 L 的公路上有一排树,每两棵相邻的树之间的间隔都是 1 米.我们可以把马路看成一个数轴,马路的一端在数轴 1 的位置,另一端在 L 的位置:数轴上的每个整数点,即 1,2,……,L,都种有一棵树. 现在要将这排树的某一段涂成某种颜色,给定 N 组区间[ 

AC日记——校门外的树(增强版) 洛谷 P1276

题目描述 校门外马路上本来从编号0到L,每一编号的位置都有1棵树.有砍树者每次从编号A到B处连续砍掉每1棵树,就连树苗也不放过(记 0 A B ,含A和B):幸运的是还有植树者每次从编号C到D 中凡是空穴(树被砍且还没种上树苗或树苗又被砍掉)的地方都补种上树苗(记 1 C D,含C和D):问最终校门外留下的树苗多少棵?植树者种上又被砍掉的树苗有多少棵? 输入输出格式 输入格式: 第一行L和N,表示校园外原来有L+1棵树,并有N次砍树或种树的操作. 以下N行,砍树或植树的标记和范围,每行3个整数.

Vijos1448校门外的树 题解

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输出一个答案 样例输入:

洛谷 P1276 校门外的树(增强版) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1276 题目描述 校门外马路上本来从编号0到L,每一编号的位置都有1棵树.有砍树者每次从编号A到B处连续砍掉每1棵树,就连树 苗也不放过(记 0 A B ,含A和B):幸运的是还有植树者每次从编号C到D 中凡是空穴(树被砍且还没种上树苗或树苗又被砍掉)的地方都补种上树苗(记 1 C D,含C和D):问最终校门外留下的树苗多少棵?植树者种上