本文主要是介绍SSL-ZYC 2646 线段树练习题三,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目大意:
给定一条长度为m的线段,有n个操作,每个操作有3个数字x,y,z表示把区间[x,y]染成颜色z。规定:线段的颜色可以相同。连续的相同颜色被视作一段。问x轴被分成多少段。
思路:
线段树
这道题与 线段树练习二 极其相似,唯一的区别在于count函数需要判断两根相交的线是否为同一个颜色。
代码:
#include <cstdio>
using namespace std;int n,m,x,y,z,sum;struct N
{int l,r,cover;
}tree[300001];void makes(int x) //建树,完全没变
{if (tree[x].r-tree[x].l<=1) return;tree[x*2].l=tree[x].l;tree[x*2].r=(tree[x].l+tree[x].r)/2;tree[x*2+1].l=(tree[x].l+tree[x].r)/2;tree[x*2+1].r=tree[x].r;makes(x*2);makes(x*2+1);
}void insert(int x,int col,int l,int r) //插入,基本没变
{if (tree[x].cover==col) return;if (l==tree[x].l&&r==tree[x].r){tree[x].cover=col;return;}if (tree[x].cover>=0) {tree[x*2].cover=tree[x*2+1].cover=tree[x].cover;tree[x].cover=-1; //变化,有多种颜色变为-1}int mid=(tree[x].l+tree[x].r)/2;if (mid>=r){insert(x*2,col,l,r);return;}if (mid<=l){insert(x*2+1,col,l,r);return;}insert(x*2,col,l,mid);insert(x*2+1,col,mid,r);
}void count(int x,int &L,int &R) //计算,基本都变了
{int ll=0,rr=0;if (tree[x].cover>=0) //一条只有一个颜色的线段{sum++;L=R=tree[x].cover;return;}if (tree[x].r==tree[x].l+1) return;count(x*2,L,ll);count(x*2+1,rr,R);if (ll==rr&&ll) sum--; //两条线段同一颜色return;
}int main()
{scanf("%d%d",&n,&m); tree[1].l=1;tree[1].r=m;makes(1); //建树for (int i=1;i<=n;i++){scanf("%d%d%d",&x,&y,&z);insert(1,z,x,y); //插入}int ak,ac;count(1,ak,ac);printf("%d\n",sum);return 0;
}
这篇关于SSL-ZYC 2646 线段树练习题三的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!