标签:
描述
校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……
如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:
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输出一个答案
5 4
1 1 3
2 2 5
1 2 4
2 3 5
样例输出
11 #include <cstdio> 2 int n,m; 3 struct node 4 { 5 int x,y; 6 int a[3];//a[1]表示左括号的数量,a[2]表示右括号的数量。 7 }t[300002]; 8 void init(int k,int l,int r)//初始化。 9 { 10 t[k].x=l; 11 t[k].y=r; 12 if(l==r)return; 13 int mid=(l+r)/2; 14 init(2*k,l,mid); 15 init(2*k+1,mid+1,r); 16 } 17 void build(int k,int l,int op) 18 { 19 if(t[k].x<=l&&l<=t[k].y)//若在当前节点的范围内,括号数量加1。 20 t[k].a[op]++; 21 if(t[k].x==t[k].y)return; 22 int mid=(t[k].x+t[k].y)/2; 23 if(l<=mid)build(2*k,l,op);//查询左儿子。 24 if(l>=mid+1)build(2*k+1,l,op);//查询右儿子。 25 } 26 int find(int k,int l,int r,int op)//查找l到r内括号的个数。 27 { 28 int ans=0; 29 if(l<=t[k].x&&t[k].y<=r)return t[k].a[op]; 30 int mid=(t[k].x+t[k].y)/2; 31 if(l<=mid)ans+=find(2*k,l,r,op); 32 if(r>=mid+1)ans+=find(2*k+1,l,r,op); 33 return ans; 34 } 35 int main() 36 { 37 int k,l,r,ans1,ans2; 38 scanf("%d%d",&n,&m); 39 init(1,1,n); 40 for(int i=1;i<=m;i++) 41 { 42 scanf("%d%d%d",&k,&l,&r); 43 if(k==1) 44 { 45 build(1,l,1); 46 build(1,r,2); 47 } 48 if(k==2) 49 { 50 ans1=ans2=0; 51 ans1=find(1,1,r,1); 52 if(l-1>=1)ans2=find(1,1,l-1,2); 53 printf("%d\n",ans1-ans2); 54 } 55 } 56 return 0; 57 }
标签:
原文地址:http://www.cnblogs.com/c0per/p/5775043.html