UVALive 6911 F - Double Swords

 

思路: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\n",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\n",cs++,st.size()); } return 0; }

 

转载于:https://www.cnblogs.com/weeping/p/5734916.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值