zoukankan      html  css  js  c++  java
  • [IOI1998] Pictures

    用线段树维护区间最小值和最小值个数来求一段区间里0的个数,把横的和竖的边分别拿出来,排序,然后每次查一下重复部分的长度即可

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    #define MAXN 5000
    #define MAXL 10000
    #define mid (T[k].l+T[k].r)/2
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    } 
     
    int n,cnt=0,ans=0;
    struct sq{
        int x1,y1,x2,y2;
    }s[MAXN+5];
    struct line{
        int k,l,r,x;
    }l[MAXL+5];
    struct TREE{
        int l,r,x,num,val;
    }T[MAXL*10];
     
    bool cmp(line x,line y){return x.x<y.x||(x.x==y.x&&x.k<y.k);}
     
    void pushdown(int k)
    {
        int ls=k<<1,rs=(k<<1)+1;
        T[ls].x+=T[k].val;T[rs].x+=T[k].val;
        T[ls].val+=T[k].val;T[rs].val+=T[k].val;
        T[k].val=0;
    }
     
    void combine(int k)
    {
        int ls=k<<1,rs=(k<<1)+1;
        if(T[ls].x==T[rs].x) T[k].x=T[ls].x,T[k].num=T[ls].num+T[rs].num;
        else if(T[ls].x<T[rs].x) T[k].x=T[ls].x,T[k].num=T[ls].num;
        else T[k].x=T[rs].x,T[k].num=T[rs].num;
    }
     
    void renew(int k,int l,int r,int ad)
    {
        if(T[k].l==l&&T[k].r==r)
        {T[k].x+=ad;T[k].val+=ad;return;}
        if(T[k].val) pushdown(k);
        if(r<=mid) renew(k<<1,l,r,ad);
        else if(l>mid) renew((k<<1)+1,l,r,ad);
        else {renew(k<<1,l,mid,ad);renew((k<<1)+1,mid+1,r,ad);}
        combine(k);
    }
     
    int query(int k,int l,int r)
    {
    //  cout<<"q"<<k<<" "<<l<<" "<<r<<endl;
        if(T[k].l==l&&T[k].r==r)
        {
            if(T[k].x>0) return T[k].r-T[k].l+1;
            else return T[k].r-T[k].l+1-T[k].num;   
        }
        if(T[k].val) pushdown(k);
        if(r<=mid) return query(k<<1,l,r);
        else if(l>mid) return query((k<<1)+1,l,r);
        else return query((k<<1)+1,mid+1,r)+query(k<<1,l,mid);
    }
     
    void init(int k,int l,int r)
    {
        //cout<<"init"<<k<<" "<<r<<endl;
        T[k].l=l;T[k].r=r;T[k].val=0;
        if(l==r){T[k].x=0;T[k].num=1;return;}
        init(k<<1,l,mid);init((k<<1)+1,mid+1,r);
        combine(k);
    }
     
    int main()
    {
        n=read();
        for(int i=1;i<=n;++i)
        {
            s[i].x1=read()+10001;s[i].y1=read()+10001;
            s[i].x2=read()+10001;s[i].y2=read()+10001;
            ans+=(s[i].x2+s[i].y2-s[i].y1-s[i].x1)*2;
            l[++cnt].k=0;l[cnt].x=s[i].x1;l[cnt].l=s[i].y1+1;l[cnt].r=s[i].y2;
            l[++cnt].k=1;l[cnt].x=s[i].x2;l[cnt].l=s[i].y1+1;l[cnt].r=s[i].y2;
        }
        sort(l+1,l+cnt+1,cmp);init(1,1,20005);
    //  for(int i=1;i<=cnt;i++)
    //  {
    //      cout<<l[i].k<<" "<<l[i].x<<" "<<l[i].l<<" "<<l[i].r<<endl;
    //  }
        for(register int i=1;i<=cnt;i++)
        {
            if(!l[i].k){ans-=query(1,l[i].l,l[i].r);renew(1,l[i].l,l[i].r,1);}
            else       {renew(1,l[i].l,l[i].r,-1);ans-=query(1,l[i].l,l[i].r);}
             
        }
        cnt=0;
        for(register int i=1;i<=n;++i)
        {
            l[++cnt].k=0;l[cnt].x=s[i].y1;l[cnt].l=s[i].x1+1;l[cnt].r=s[i].x2;
            l[++cnt].k=1;l[cnt].x=s[i].y2;l[cnt].l=s[i].x1+1;l[cnt].r=s[i].x2;
        }
        sort(l+1,l+cnt+1,cmp);init(1,1,20005);
    //  for(int i=1;i<=cnt;i++)
    //  {
    //      cout<<l[i].k<<" "<<l[i].x<<" "<<l[i].l<<" "<<l[i].r<<endl;
    //  }
        for(register int i=1;i<=cnt;i++)
        {
            if(!l[i].k){ans-=query(1,l[i].l,l[i].r);renew(1,l[i].l,l[i].r,1);}
            else       {renew(1,l[i].l,l[i].r,-1);ans-=query(1,l[i].l,l[i].r);}
        }
        printf("%d",ans);
        return 0;
    }
    FallDream代表秋之国向您问好! 欢迎您来我的博客www.cnblogs.com/FallDream
  • 相关阅读:
    STL堆算法性能分析与优化方法(GCC4.4.2 stl_heap.h源代码分析与改进方案)
    POJ 1631 Bridging Singnals
    一个用于读unicode文本的迭代器(iterator)
    常用文本压缩算法及实现(To be finshed!)
    volatile语义及线程安全singleton模式探讨
    C++实现的huffman与canonical huffman的压缩解压缩系统,支持基于单词的压缩解压缩
    linux环境下 C++性能测试工具 gprof + kprof + gprof2dot
    多线程统计多个文件的单词数目C++0x多线程使用示例
    python嵌入C++ boost.python如何在C++中调用含有不定长参数tuple变量和关键字参数dict变量的函数
    boost.python入门教程 python 嵌入c++
  • 原文地址:https://www.cnblogs.com/FallDream/p/ioi1998.html
Copyright © 2011-2022 走看看