ZOJ 3518 Unsafe Factor(离散化)

来源:互联网 发布:ait8328 编程 编辑:程序博客网 时间:2024/06/08 13:51

Xiao Ming has two paper tapes with the same length. He wants to use them to hang some weight. But XiaoMing finds that the paper tape may have some damaged areas, which will make the tape easier to be broken. For clever Xiao Ming, he sticks these two tapes up from the start point to the end point.

But there is a new problem, after paste, in some place the tape may exist hidden flaw. Hidden flaw means at this place, one of the two tape has damaged areas before paste, but after paste, this kind of damaged areas may be difficult to be found, otherwise, if both of the tapes at some places have damaged areas, they are still visible after pasting.

After this paste work, his father goes back home and finds XiaoMing's perfect work. His father finds damaged areas which are still visible on the new tape and fixs it. Oh, what an adorable father he is!

Because of the hidden damaged areas, there is still unsafe factor. We define the "Unsafe Factor" as the longest length of the successive hidden damaged areas.

Your task is to calculate the "Unsafe Factor".

NOTICE: the damaged areas are regarded as a point on the tape.

Input

The input file contains several test cases (no more than 20).

For each case, the first line contains three integers L, n1, n2 (0 < L ≤ 10000000, 0 ≤ n1, n2 ≤ 100000) which indicate the length of the tape, the number of the damaged area intervals for tape 1 and the number of the damaged area intervals for tape 2. Then follows n1 and n2 lines. The format of each line is two integer "x y" (0 ≤ x ≤ y < L), indicate there are damaged areas at x to y (x, x+1, x+2, x+3, ... y point have a damaged area).

We ensure that each damaged area is told only once in the input file for each case.

Output

For each case, output the "Unsafe Factor" in a single line.

Sample Input
10 3 21 45 68 91 16 7
Sample Output
4
Hint

Because of huge input, scanf is recommended.


题解:

题意:

翻译成中国话就是给你个全长len,n1+n2个区间,每次操作是将区间内所有整数节点+1,最终求最长的连续1的长度

思路:

看到数据那么大就想到了离散化,一开始想用线段树做,后来发现只要离散化就行了,然后暴力扫一遍离散化后的节点

代码:

#include<algorithm>#include<iostream>#include<cstring>#include<stdio.h>#include<math.h>#include<string>#include<stdio.h>#include<queue>#include<stack>#include<map>#include<deque>#define M (t[k].l+t[k].r)/2#define lson k*2#define rson k*2+1using namespace std;int xx[600005];//存离散化后线段的端点int p[200005];//存区间情况struct node{    int l,r;}a[200005];//存要+1的区间int main(){    int i,j,k,n,m,len,x,y,ans,l,r,maxx,tag,tot;    while(scanf("%d%d%d",&len,&n,&m)!=EOF)    {        n+=m;        ans=0;        for(i=0;i<n;i++)        {            scanf("%d%d",&a[i].l,& a[i].r);            xx[ans]=a[i].l;            xx[ans+1]=a[i].r;            xx[ans+2]=a[i].r+1;//我是为了防止离散出错加上的了一个端点            ans+=3;        }        sort(xx,xx+ans);//排序才能去重        ans=unique(xx,xx+ans)-xx;//离散化去重        memset(p,0,sizeof(p));        for(i=0;i<n;i++)        {            l=lower_bound(xx,xx+ans,a[i].l)-xx;            r=lower_bound(xx,xx+ans,a[i].r+1)-xx;//找出两个端点对应离散化后数组的下标            for(j=l;j<r;j++)            {                p[j]++;//遍历++            }        }        maxx=0;        for(i=0;i<ans;i++)//暴力遍历一遍离散化后的数组        {            if(p[i]!=1)//从1开始找                continue;            len=1;            j=1;            while(i+j<ans&&p[i+j]==1)            {                j++;            }//记录长度            if(j!=1)                len=xx[i+j]-xx[i];            if(len>maxx)//取最长                maxx=len;            i+=(j-1);//跳掉一部分查找        }        printf("%d\n",maxx);    }    return 0;}


原创粉丝点击