码迷,mamicode.com
首页 > 其他好文 > 详细

一道题的不断进取!!!

时间:2017-10-09 22:44:28      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:printf   set   freopen   比赛   res   files   alt   efi   namespace   

区间

题目描述:

技术分享

样例输入:

样例1:
3
1 3
2 2
1 2

样例2:
5
3 5
2 5
1 5
1 5
4 5

样例3:
20
13 16
3 17
1 6
16 20
3 13
10 13
5 19
3 20
5 7
15 16
10 16
9 20
1 13
14 16
6 11
3 4
3 11
1 14
10 11
10 13

样例输出:

样例1:
2

样例2:
3

样例3:
7

提示:

【数据规模】
对于20% 的数据, N<=20。
对于40% 的数据, N<=100。
对于60% 的数据, N<=2000。
对于80% 的数据, N<=80000。
对于100% 的数据, N<=300000。

为了强行增加难度,这道题似乎是卡常数的?

时间限制:1000ms
空间限制:256MByte

 

比赛时自己打的n*n*logn

#include<bits/stdc++.h>
#define maxn 300300
using namespace std;

int n,l=1,r,ans,ma,ce,le[maxn],re[maxn];

inline int check(int len)
{
    int tot = 0;
    for(int i=1;i<=n-len + 1;i++)
    {
        int x = i;
        int y = i + len - 1;
        int k = 0;
        for(int j=1;j<=n;j++)
        {
            if(le[j] <= x && y <= re[j]) k++;
        }
        tot = max(tot , k);
    }    
    return tot;
}

main(){
//    freopen("data.in","r",stdin);
//    freopen("C.out","w",stdout);
        
    scanf("%d",&n);
    
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&le[i],&re[i]);
    }
    
    r = n;
    
    while(l < r)
    {
        int mid = l + r >> 1;
        ce = check(mid);
        if(ce < mid) r = mid;
        else l = mid + 1;
        ans = max(ans , min(ce , mid));
    }
    
    printf("%d",ans);    
}

 

然后学姐教了我一种n*logn*logn的做法

#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 300300
#define lb(x) x&-x
using namespace std;
int n,l,r,ma,k,f[maxn];

struct st{
    int l,r;
}s[maxn];

bool com(st a,st b)
{
    if(a.l != b.l) return a.l < b.l;
    return a.r < b.r;
}

void up(int pos)
{
    while(pos < maxn)
    {
        f[pos]++;
        pos+=lb(pos);
    }
}

int cha(int pos)
{
    int ans = 0;
    while(pos)
    {
        ans += f[pos];
        pos -= lb(pos);
    }
    return ans;
}

int pan(int x)
{
    int d;
    int ans = 0;
    for(int i=1;i<=n;i++)
    {
        if(s[i].r - s[i].l + 1 < x) continue;
        d = s[i].l;
        up(s[i].r);
        ans = cha(maxn - 1) - cha(d + x - 2);
        if(ans >= x) return 1;
    }
    return 0;
}

main(){
    
    scanf("%d",&n);
    
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&s[i].l,&s[i].r);
    }
    
    sort(s+1,s+1+n,com);
    
    l = 1;
    
    r = n;
    
    while(l < r)
    {
        int mid = l + r >> 1;
        memset(f,0,sizeof(f));
        if(pan(mid)) l = mid + 1;
        else r = mid;
    }
    
    printf("%d",l - 1);
}

 

最后%%%kcz%%%教了我一种n*logn的做法

#include<cstdio>
#include<cstring>
#define maxn 300300
using namespace std;
int n,l,r,ma,k,f[maxn];

struct st{
    int l,r;
}s[maxn];

int pan(int x)
{
    memset(f,0,sizeof(f));
    int ans = 0,ce = 0;
    for(int i=1;i<=n;i++)
    {
        if(s[i].r - s[i].l + 1 < x) continue;
        f[s[i].l]++;
        f[s[i].r - x + 2]--;
    }
    for(int i=1;i<=n;i++)
    {
        ans+=f[i];
        if(ans >= x) return 1;
    }
    return 0;
}

main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d%d",&s[i].l,&s[i].r);
    l = 1;
    r = n;
    while(l < r)
    {
        int mid = l + r >> 1;
        if(pan(mid)) l = mid + 1;
        else r = mid;
    }
    printf("%d",l - 1);
}

 

最后时间一路飙升

技术分享

 

技术分享

 

技术分享

最后跑得比孔爷还快!!!

技术分享

还是先%为敬!!!

%%%KCZNO1%%%

 

一道题的不断进取!!!

标签:printf   set   freopen   比赛   res   files   alt   efi   namespace   

原文地址:http://www.cnblogs.com/kczno1fans/p/7642865.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!