思路:1.把所有有长度的剑看做点。Ai点是肯定要取。然后求另一把剑。
先对右区间排个序,然后每次看这个区间范围内有没有剑,如果没有就添加一把(值为右端点的剑);
如果有并且数量为1且这条龙的Ai等这把剑的长度的话,说用还需要一把剑,再添加一把。
否则不添加。
至于怎么查询某个区间有没有剑,可以用树状数组,线段树之类的。
2.也是先排序,然后set模拟。。。。具体看第二份代码吧,懒得打字了。
#include <bits/stdc++.h> #define PB push_back #define MP make_pair using namespace std; typedef long long LL; typedef pair<int,int> PII; #define PI acos((double)-1) #define E exp(double(1)) #define K 1000000+9 struct node { int a,b,c; }sw[100002]; int n,c[2*K],mx,vis[K]; bool cmp(node ta,node tb) { if(ta.c==tb.c) return ta.b<tb.b; return ta.c<tb.c; } void add(int x,int v) { while(x<=mx) { c[x]+=v; x+=x&(-x); } } int get_sum(int x) { int sum=0; while(x>0) { sum+=c[x]; x-=x&(-x); } return sum; } int main(void) { int t,cs=1;cin>>t; while(t--) { set<int>st; cin>>n; memset(c,0,sizeof(c)); memset(vis,0,sizeof(vis)); mx=0; for(int i=1;i<=n;i++) { scanf("%d%d%d",&sw[i].a,&sw[i].b,&sw[i].c); mx=max(mx,max(sw[i].a,sw[i].c)); } for(int i=1;i<=n;i++) if(!vis[sw[i].a]) add(sw[i].a,1),vis[sw[i].a]=1; sort(sw+1,sw+1+n,cmp); for(int i=1;i<=n;i++) { int cnt=get_sum(sw[i].c)-get_sum(sw[i].b-1); if(sw[i].a>=sw[i].b &&sw[i].a<=sw[i].c && cnt==1) add(sw[i].c,1); else if(!cnt) add(sw[i].c,1); } printf("Case #%d: %d ",cs++,get_sum(sw[n].c)); } return 0; }
#include <bits/stdc++.h>
#define PB push_back
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
#define PI acos((double)-1)
#define E exp(double(1))
#define K 100000+9
struct node
{
int a,b,c;
}sw[K];
int n;
bool cmp(node ta,node tb)
{
if(ta.c==tb.c)
return ta.b<tb.b;
return ta.c<tb.c;
}
int main(void)
{
int t,cs=1;cin>>t;
while(t--)
{
set<int>st;
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&sw[i].a,&sw[i].b,&sw[i].c);
st.insert(sw[i].a);
}
sort(sw+1,sw+1+n,cmp);
for(int i=1;i<=n;i++)
{
set<int>::iterator it=st.lower_bound(sw[i].b);
if(it!=st.end() && *it==sw[i].a)it++;
if(it==st.end() || *it>sw[i].c )
if(sw[i].c==sw[i].a)
st.insert(-sw[i].c);
else
st.insert(sw[i].c);;
}
printf("Case #%d: %d
",cs++,st.size());
}
return 0;
}