ZUFEOJ 2147 07染色带谜题
2147: 07染色带谜题
时间限制: 1 Sec 内存限制: 128 MB提交: 170 解决: 21
[提交][状态][讨论版][Edit] [TestData]
题目描述
现在给你一个长为N的染色带,有M种颜色,标号分别为0,1,2,…,M-1,染色带初始的颜色为标号0,现在对它进行K次操作,第i次操作,是对染色带的[Li,Ri]区间染上第Si种颜色(即把这段区间原来的颜色给覆盖掉),最后问你染色带进行这么多次操作后染色带上有几种颜色。
输入
输入包含多组数据,每组数据第一行包含3个正整数分别是N,M,K(0<N<=10000000,0<M<=10000,0<K<=10000),它们用空格隔开,接下来K行分别是3个整数Li ,Ri,Si,分别满足0<=Li <Ri<=N, 0<=Si<M。
输出
输出对于每组数据输出一个数字代表染色带上最后有几种颜色。
样例输入
2 2 0
2 2 1
0 2 1
3 3 3
0 2 1
1 3 2
2 3 0
样例输出
1
1
3
首先吐槽一下题目,第一句,应该是$n+1$长度的吧。。。直接上了个线段树区间覆盖,写完一直$WA$,对拍去了,发现标程是错的,数据也是错的。搞笑的是这题是$2014$年学校校赛的题目,当时数据就是错的,但是现场有人$AC$。。现在我把数据改正确了,历史翻案。
#include<map> #include<set> #include<ctime> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<functional> using namespace std; int n,m,k; int L[100010],R[100010],s[100010]; int p[100010],sz; int t[400010],y[100010]; set<int>r; int get(int x) { int left =1,right =sz,res; while(left<=right) { int mid = (left + right)/2; if(p[mid]>x) right = mid-1; else if(p[mid]==x) res=mid,right = mid-1; else left = mid+1; } return res; } void pushDown(int rt) { if(t[rt]==-1) return ; t[2*rt] = t[rt]; t[2*rt+1] = t[rt]; t[rt]=-1; } void update(int LL,int RR,int col,int l,int r,int rt) { if(LL<=l&&r<=RR) { t[rt]=col; return ; } int m = (l+r)/2; pushDown(rt); if(LL<=m) update(LL,RR,col,l,m,2*rt); if(RR>m) update(LL,RR,col,m+1,r,2*rt+1); } void dfs(int l,int r,int rt) { if(l==r) { y[t[rt]]=1; return ; } int m = (l+r)/2; pushDown(rt); dfs(l,m,2*rt); dfs(m+1,r,2*rt+1); } void build(int l,int r,int rt) { if(l==r) { t[rt]=0; return ; } t[rt]=-1; int m = (l+r)/2; build(l,m,2*rt); build(m+1,r,2*rt+1); } int main() { //freopen("D:\\out.txt","w",stdout); while(~scanf("%d%d%d",&n,&m,&k)) { sz=0; memset(t,0,sizeof t); memset(y,0,sizeof y); r.clear(); for(int i=1;i<=k;i++) { scanf("%d%d%d",&L[i],&R[i],&s[i]); if(r.count(L[i])==0) sz++, p[sz]=L[i] , r.insert(L[i]); if(r.count(R[i])==0) sz++, p[sz]=R[i] , r.insert(R[i]); if(r.count(L[i]-1)==0&&L[i]-1>=0) sz++, p[sz]=L[i]-1 , r.insert(L[i]-1); if(r.count(L[i]+1)==0&&L[i]+1<=n) sz++, p[sz]=L[i]+1 , r.insert(L[i]+1); if(r.count(R[i]-1)==0&&R[i]-1>=0) sz++, p[sz]=R[i]-1 , r.insert(R[i]-1); if(r.count(R[i]+1)==0&&R[i]+1<=n) sz++, p[sz]=R[i]+1 , r.insert(R[i]+1); } if(r.count(0)==0) sz++, p[sz]=0 , r.insert(0); if(r.count(n)==0) sz++, p[sz]=n , r.insert(n); sort(p+1,p+1+sz); build(1,sz,1); for(int i=1;i<=k;i++) L[i] = get(L[i]), R[i] = get(R[i]); for(int i=1;i<=k;i++) update(L[i],R[i],s[i],1,sz,1); dfs(1,sz,1); int ans=0; for(int i=0;i<=100000;i++) ans=ans+y[i]; printf("%d\n",ans); } return 0; }