P a b:询问从a到b的线段上有多少种颜色。
思路:线段树的应用,另外还用到了一个线段树常用的思路——lazy。lazy顾名思义就是懒惰——这里是指在更新的时候,不必更新到每条元线段。
#include <iostream> using namespace std; #include <stdio.h> #include <string.h> #include <memory.h> const int MAXN = 100005; const int COLOR_NUM=35; const int DEFAULT_COLOR=0; struct node { int left; int right; int color; }; node tree[MAXN*5]; bool visit[COLOR_NUM]; int l; void build(const int &left, const int &right, const int &node_num=1) { tree[node_num].left=left; tree[node_num].right=right; tree[node_num].color=DEFAULT_COLOR; if (left==right) return; int mid = (left+right) >> 1; build(left,mid,2*node_num); build(mid+1,right,2*node_num+1); } void init() { build(1,l); tree[1].color=1; } void insert(const int &left, const int &right, const int &color, const int &node_num = 1 ) { if (left==tree[node_num].left&&right==tree[node_num].right) { tree[node_num].color=color; return; } if (tree[node_num].color!=DEFAULT_COLOR) { tree[node_num*2].color=tree[node_num].color; tree[node_num*2+1].color=tree[node_num].color; tree[node_num].color=DEFAULT_COLOR; } int mid=(tree[node_num].left+tree[node_num].right) >> 1; if (right<=mid) insert(left,right,color,node_num*2); else if (left>mid) insert(left,right,color,node_num*2+1); else { insert(left,mid,color,node_num*2); insert(mid+1,right,color,node_num*2+1); } } int query(const int &left, const int &right, const int &node_num=1) { int ctr=0; if (tree[node_num].color!=DEFAULT_COLOR) { if (visit[tree[node_num].color]==false) { ctr++; visit[tree[node_num].color]=true; } return ctr; } int mid = (tree[node_num].left+tree[node_num].right) >> 1; if (right<=mid) ctr+=query(left,right,node_num*2); else if (left>mid) ctr+=query(left,right,node_num*2+1); else { ctr+=query(left,mid,node_num*2); ctr+=query(mid+1,right,node_num*2+1); } return ctr; } int main() { int t,o,i; char operation; int a,b,c,temp; scanf("%d%d%d",&l,&t,&o); init(); while (o--) { getchar(); scanf("%c",&operation); if (operation=='C') { scanf("%d%d%d",&a,&b,&c); if (a>b) { temp=a; a=b; b=temp; } insert(a,b,c); } else { scanf("%d%d",&a,&b); if (a>b) { temp=a; a=b; b=temp; } memset(visit,false,sizeof(visit)); printf("%d\n",query(a,b)); } } return 0; }