zoukankan      html  css  js  c++  java
  • 并不对劲的CF1194E:Count The Rectangles

    题意

    (n)(nleq 5000))个平行于x轴或平行于y轴的线段。求这些线段围成了多少个长方形。由多个长方形拼成的也算。

    题解

    考虑暴力的做法:先分别计算每条横着的线与哪些竖着的线有交点,再枚举两条横着的线,求与它们都有交点的线的个数,在这些线中选两条和这两条横着的线拼成长方形。
    发现与同一条竖着的线有交点的横线一定是把所有横线按纵坐标排序后连续的一段。
    感谢伟大的YSF!!!

    代码

    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<iomanip>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define rep(i,x,y) for(register int i=(x);i<=(y);++i)
    #define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
    #define view(u,k) for(int k=fir[u];~k;k=nxt[k])
    #define LL long long
    #define maxn 5007
    using namespace std;
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)&&ch!='-')ch=getchar();
        if(ch=='-')f=-1,ch=getchar();
        while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
        return x*f;
    }
    void write(LL x)
    {
        if(x==0){putchar('0'),putchar('
    ');return;}
        int f=0;char ch[20];
        if(x<0)putchar('-'),x=-x;
        while(x)ch[++f]=x%10+'0',x/=10;
        while(f)putchar(ch[f--]);
        putchar('
    ');
        return;
    }
    struct node{int x,l,r;}a[maxn],b[maxn];
    int n,tr[maxn+maxn],maxk=5001,sz=10002,cnta,cntb;
    LL ans;
    vector<int>ed[maxn];
    node maken(int x,int l,int r){node tmp;tmp.x=x,tmp.l=l,tmp.r=r;return tmp;}
    LL c(int x){return (LL)x*(x-1ll)/2ll;}
    int lt(int x){return x&(-x);}
    void add(int x,int k){for(;x<=sz;x+=lt(x))tr[x]+=k;return;}
    int ask(int x){int k=0;for(;x;x-=lt(x))k+=tr[x];return k;}
    int yes(node x,node y)
    {
    	if(y.l<=x.x&&x.x<=y.r&&x.l<=y.x&&y.x<=x.r)return 1;
    	return 0;
    }
    bool cmpx(node x,node y){return x.x<y.x;}
    bool cmpr(int x,int y){return b[x].r<b[y].r;}
    int main()
    {
        n=read();
        rep(i,1,n)
        {
        	int x1=read(),y1=read(),x2=read(),y2=read();
        	if(x1>x2)swap(x1,x2);
        	if(y1>y2)swap(y1,y2);
        	if(y1==y2)a[++cnta]=maken(y1,x1,x2);
        	else b[++cntb]=maken(x1,y1,y2);
        }
        sort(a+1,a+cnta+1,cmpx);
        rep(i,1,cnta)
        {
        	rep(j,1,cntb)if(yes(a[i],b[j]))
        	{
        		add(b[j].x+maxk,1);
        		ed[i].push_back(j);
        	}
    		int li=ed[i].size(),now=-1;
        	sort(ed[i].begin(),ed[i].end(),cmpr);
        	rep(j,i+1,cnta)
        	{
        		while((now+1)<li&&b[ed[i][now+1]].r<a[j].x)add(b[ed[i][now+1]].x+maxk,-1),now++;
        		int num=ask(a[j].r+maxk)-ask(a[j].l+maxk-1);
    			ans+=c(num);
        	}
        	while((now+1)<li)add(b[ed[i][now+1]].x+maxk,-1),now++;
        }
        write(ans);
    	return 0;
    }
    
  • 相关阅读:
    Java初学者的学习路线推荐
    C#基础(七)虚函数
    C#基础(六)--枚举的一些常用操作
    C#基础(五)--枚举的含义及其应用
    C#基础(四)--值类型和引用类型,栈和堆的含义
    C#基础(三)--运算符及条件控制语句
    Zipkin+Sleuth调用链监控集成和使用
    jenkins集成cucumber-resport报告
    微信小程序自动化,记录趟过的坑!
    解压版mysql+免破解版Navicat,好用!
  • 原文地址:https://www.cnblogs.com/xzyf/p/11647735.html
Copyright © 2011-2022 走看看