zoukankan      html  css  js  c++  java
  • UCF Local Programming Contest Round 1A——I.Check List(线段树)

    参考博客

    题意:

    求满足(x1<x2<x3)(y2<y1<y3)的三元组个数

    思路:

    不难想到先对(x)排序,再处理(y)的情况,然后就推不出来了。
    应当排序后枚举每个点,每次将该点与前面的点统计答案,再将该点的贡献更新。
    假设(sum1)表示第一个点的个数,(sum2)表示满足(x1<x2)(y2<y1)的二元组个数。
    假设枚举到的点为((x,y))

    • 统计答案:查找(1<=y_{j}<y)(sum2)值即为答案,因为(sum2)已经满足二元组,(x)已经排序,(y_{j}<y),满足三元组。
    • 更新贡献:
      更新(sum2):对于([y,+infty])(sum1)都可以与((x,y))构成合法的二元组,所以要将([y,+infty])(sum2)全部加(sum1).
      更新(sum1):当枚举到后面的点时,点((x,y))可以作为第一个点,所以(y的sum1++)
      区间修改单点修改区间查询用线段树来维护,先按(x)排序,再对(y)坐标离散化,建树。
      只有(sum2)用到了区间修改的操作所以懒惰标记只记录(sum2)的就好。注意相同(x)轴坐标的要一起处理。

    代码:

    const int maxn=1e5+100;
    struct node{
        int x,y;
        bool operator<(const node& a)const{
            return x<a.x;
        }
    };
    node p[maxn];
    vector<int>v;
    int n;
    struct node1{
        int l,r;
        ll sum1,sum2,laz;///sum2的懒惰标记
    }tr[maxn*4];
    
    void pushup(int u){
    	tr[u].sum1=tr[u<<1].sum1+tr[u<<1|1].sum1;
    	tr[u].sum2=tr[u<<1].sum2+tr[u<<1|1].sum2;
    }
    
    void pushdown(int u){
    	if(tr[u].laz){
    		tr[u<<1].laz+=tr[u].laz;
    		tr[u<<1|1].laz+=tr[u].laz;
    		tr[u<<1].sum2+=tr[u<<1].sum1*tr[u].laz;
    		tr[u<<1|1].sum2+=tr[u<<1|1].sum1*tr[u].laz;
    		tr[u].laz=0;
    	}
    }
    
    void build(int u,int l,int r){
    	tr[u].l=l,tr[u].r=r;
    	tr[u].sum1=tr[u].sum2=tr[u].laz=0;
    	if(l==r) return ;
    	int mid=(l+r)/2;
    	build(u<<1,l,mid);build(u<<1|1,mid+1,r);
    }
    
    void update1(int u,int pos){//dan dian
    	if(tr[u].l==tr[u].r){
    		tr[u].sum1++;
    		return ;
    	}
    	int mid=(tr[u].l+tr[u].r)/2;
    	pushdown(u);
    	if(pos<=mid) update1(u<<1,pos);
    	else update1(u<<1|1,pos);
    	pushup(u);
    }
    
    void update2(int u,int l,int r){
    	if(tr[u].r<l||tr[u].l>r) return ;
    	if(tr[u].l>=l&&tr[u].r<=r){
    		tr[u].sum2+=tr[u].sum1;
    		tr[u].laz++;
    		return ;
    	}
    	pushdown(u);
    	update2(u<<1,l,r);update2(u<<1|1,l,r);
    	pushup(u);
    }
    
    ll qask(int u,int l,int r){
    	ll res=0;
    	if(tr[u].r<l||tr[u].l>r) return 0;
    	if(tr[u].l>=l&&tr[u].r<=r){
    		return tr[u].sum2;
    	}
    	pushdown(u);
    	res=qask(u<<1,l,r)+qask(u<<1|1,l,r);
    	return res;
    	
    }
    
    int get(int y){
    	return lower_bound(v.begin(),v.end(),y)-v.begin()+1;
    }
    
    int main(){
        n=read;
        rep(i,1,n){
        	p[i].x=read,p[i].y=read;
        	v.push_back(p[i].y);
        }
        sort(p+1,p+1+n);
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
        build(1,1,v.size());
        ll res=0;
        rep(i,1,n){
        	int j;
        	for(j=i;j<=n&&p[i].x==p[j].x;j++)
        		res=res+qask(1,1,get(p[j].y)-1);
        	for(j=i;j<=n&&p[i].x==p[j].x;j++)
        		update2(1,get(p[j].y)+1,v.size());
        	for(j=i;j<=n&&p[i].x==p[j].x;j++)
        		update1(1,get(p[j].y));
        	i=j-1;
        }
        printf("%lld
    ",res);
        return 0;
    }
    
    
  • 相关阅读:
    docker学习笔记1-- 用Toolbox安装Docker--介绍Docker Machine
    IDEA中文出现乱码解决
    hadoop本地运行与集群运行
    关于IDEA导出项目jar包/runnable jar
    IDEA 添加jar包的三种方式(重点:new uer Libraries)
    windows下客户端开发hdf--环境搭建
    junit在idea中的使用(1)--理论篇
    word的"bug"
    第4章 控制执行流程
    第3章 操作符
  • 原文地址:https://www.cnblogs.com/OvOq/p/15035539.html
Copyright © 2011-2022 走看看