• poj_3067 树状数组


    题目大意

        左右两个竖排,左边竖排有N个点,从上到下依次标记为1,2,...N; 右边竖排有M个点,从上到下依次标记为1,2....M。现在从K条直线分别连接左边一个点和右边一个点,求这K条直线的交点个数(左右竖排上的点不算做交点)。 
        给出N,M,K,以及K条线的起点和终点。

    题目分析

        求两两交点的问题最好固定顺序,如i和i之前的交点,这样便于统计而不重复不遗漏。在将K条线按照左边点从小到大的顺序进行排序,左边点相同按照右边点从小到大排序之后,按照顺序分析当前线和它之前的线的交点个数: 
        当前线k的左边点序号为 xa, 右边点序号为 ya, 则对于当前线k之前的那些线1--k-1,他们左边点的序号肯定小于等于xa, 这些线(1--k-1)中右边点序号大于 ya的那些线会和当前线k有一个交点。因此对于当前线k,统计之前1---k-1线的右边点在 [ya + 1--M]中的个数,形成了一个区间统计问题。 
        考虑右边点1,2....M 各对应一个统计变量 count[i], 每次分析线k,都将线k的右边点ya 对应的count[ya] ++。 这样,每次都统计 [t, M]区间内 count[i]的和。 使用树状数组来实现。

    实现(c++)

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<vector>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    #define MAX_CITY_NUM 1002
    
    
    struct Highway{
    	int east_city;
    	int west_city;
    	Highway(int e, int w):
    	east_city(e), west_city(w){
    	}
    };
    vector<Highway> gHws;
    int gC[MAX_CITY_NUM];
    int gLowbit[MAX_CITY_NUM];
    
    bool Cmp(const Highway& h1, const Highway& h2){
    	if (h1.east_city == h2.east_city)
    		return h1.west_city < h2.west_city;
    	return h1.east_city < h2.east_city;
    }
    
    
    void InitLowbit(int n){
    	for (int i = 1; i <= n; i++){
    		gLowbit[i] = i&(-i);
    	}
    }
    void InitSequence(int n){
    	memset(gC, 0, sizeof(gC));
    }
    
    void Update(int k, int n, int add){
    	while (k <= n){
    		gC[k] += add;
    		k += gLowbit[k];
    	}
    }
    
    int Query(int k){
    	int result = 0;
    	while (k > 0){
    		result += gC[k];
    		k -= gLowbit[k];
    	}
    	return result;
    }
    
    int main(){
    	int cas, N, M, K, e_city, w_city;
    	scanf("%d", &cas);
    	InitLowbit(1001);
    	for (int c = 1; c <= cas; c++){
    		scanf("%d %d %d", &N, &M, &K);
    		gHws.clear();
    		InitSequence(M);
    		for (int i = 1; i <= K; i++){
    			scanf("%d %d", &e_city, &w_city);
    			gHws.push_back(Highway(e_city, w_city));
    		}
    		sort(gHws.begin(), gHws.end(), Cmp);
    		long long int crossing = 0;
    		for (int i = 0; i < K; i++){
    			crossing += (Query(M) - Query(gHws[i].west_city));
    			Update(gHws[i].west_city, M, 1);
    		}
    		printf("Test case %d: %lld
    ", c, crossing);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Docker & ASP.NET Core (3):发布镜像
    Docker & ASP.NET Core (2):定制Docker镜像
    Docker & ASP.NET Core (1):把代码连接到容器
    Redis五大数据类型的常用操作
    centos安装Redis
    SpringBoot进阶教程(五十一)Linux部署Quartz
    mybatis在xml文件中处理转义字符
    org.apache.ibatis.builder.IncompleteElementException: Could not find result map java.lang.Integer
    SpringBoot进阶教程(五十)集成RabbitMQ---MQ实战演练
    浅谈RabbitMQ Management
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4794694.html
Copyright © 2020-2023  润新知