POJ 3067 Japan (树状数组 && 控制变量)

题意: 西海岸和东海岸有分别有n (1~n)个和m (1~m)个城市, 两个海岸的城市之间有k条公路连通, 公路会相交, 现在给出城市和公路的信息问你由这些公路组成的复杂交通有多少个交点 (如果两个条公路的起点或者终点相同那这两点不算做相交)

分析: 这里公路信息用(x, y)二元组来表示西海岸的x城市与东海岸的y城市相连, 首先自然想到给k个公路的信息按x或y排个序, 否则变量太乱不助于思考!先设想按x升序排序且先不管x相等的情况, 如果x是升序的, 那我在考虑第i条公路的时候是不是只要关心yi值是否比之前所有的点的y值大就行了, 如果比所有之前的点的y值都大, 则之前没有线yi相交, 否则有之前有j个比它大的则就将多产生j个交点。这样去控制变量的计算方法可以自然与求逆序对联系到一起, 细想如果我先按x升序再按y升序, 那按照上面所述的方法, 是不是只要求出此时y数列的逆序对个数即可?那如果x相等怎么办呢?很显然, 如果x相等, 由于题目说 (如果两个条公路的起点或者终点相同那这两点不算做相交) , 那这两条线必定不能产生交点, 即不能在在线计算的过程中产生逆序对, 那只要先处理y比较小的即可, 也就是为什么x相等就按y从小到大排序的理由。既然是求逆序对, 便用到树状数组了!

瞎想: 可以发现在用树状数组解决问题时候, 应该多去想如何控制变量或者使变量单一(排序或者....其他), 或者将其变成求逆序数的经典模型, 或者将区间(一般是两端点)转画成直角坐标系里的x,y等方法来寻求规律!

瞎搞: 当时想偷偷懒, 用个set< pair<int, int> >来存储, 的确也能做到, 不过TLE的我眼泪掉下来!还有就是最后的ans是交点个数, 可以很大, 我一开始缺用了int, 最后才发现啊!

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<set>
#define LL long long
#define lowbit(i) (i&(-i))
using namespace std;
int c[1001], n, k, m;
inline void add(int i, int val)
{
    while(i<=m){//由于是求y序列所以这里上限是m
        c[i] += val;
        i += lowbit(i);
    }
}
LL sum(int i)
{
    LL ans = 0;
    while(i>0){
        ans += c[i];
        i -= lowbit(i);
    }
    return ans;
}
typedef struct stru
{
    int x, y;
}A;
A arr[10000000];
bool cmp(const A fir, const A sec)
{
    if(fir.x == sec.x) return fir.y < sec.y;
    return fir.x < sec.x;
}
int main(void)
{
    int nCase;
    scanf("%d", &nCase);
    for(int t=1; t<=nCase; t++){
        memset(c, 0, sizeof(c));
        scanf("%d%d%d", &n, &m, &k);
        for(int i=0; i<k; i++){
            scanf("%d%d", &arr[i].x, &arr[i].y);
        }
        sort(arr, arr+k, cmp);//先按x升序,若x相等则按y升序
        LL ans = 0; //注意是long long
        for(int i=0; i<k; i++){//树状数组求y序列的逆序对,经典求法
            ans += i - sum(arr[i].y);//这里不必避免参数为0的坑,因为最小为1
            add(arr[i].y, 1);
        }
        printf("Test case %d: %lld\n", t, ans);
    }
    return 0;
}

时间: 2024-11-03 22:13:28

POJ 3067 Japan (树状数组 && 控制变量)的相关文章

POJ 3067 Japan 树状数组求逆序对

题目大意:有两排城市,这两排城市之间有一些路相互连接着,求有多少条路相互交叉. 思路:把所有的路先按照x值从小到大排序,x值相同的按照y值从小到大排序,然后插入边的时候,先找有多少比自己y值小的,这些边的x值一定比自己大,也就是一个逆序对,然后统计起来.记得答案要用long long (__int64) CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorith

poj3067 Japan(树状数组)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://poj.org/problem?id=3067 Description Japan plans to welcome the ACM ICPC World Finals and a lot of roads must be built for the venue. Japan is tall island with N cities on the East coast and M cities

POJ 2309 BST 树状数组基本操作

Description Consider an infinite full binary search tree (see the figure below), the numbers in the nodes are 1, 2, 3, .... In a subtree whose root node is X, we can get the minimum number in this subtree by repeating going down the left node until t

Poj 2299 Ultra-QuickSort 树状数组 解法

本题的树状数组稍微有点特点,就是需要所谓的离散化一下,开始听这个名称好像很神秘的,不过其实很简单. 就是把一个数组arr的值,其中的值是不连续的,变成一组连续的值,因为这样他们的顺序是不变的,所以,不影响结果. 例如:9 1 0 5 4 ->变为:5 2 1 4 3看出他们的相对位置不变的. 9和5为最大值在第一个位置,1和2为第二大的值在第二个位置,0和1在第一个位置等,看出对应顺序了吗? 对,就是这么简单的方法, 就叫做离散化. 如果你对counting sort熟悉的话,那么这样的思想理解

POJ 2481 Cows(树状数组)

Description Farmer John's cows have discovered that the clover growing along the ridge of the hill (which we can think of as a one-dimensional number line) in his field is particularly good. Farmer John has N cows (we number the cows from 1 to N). Ea

POJ3067 Japan 树状数组的应用

这题以前做过,用的线段树,现在用树状数组做一次, 题意:给你n个城市在日本左边,m个城市在日本右边,然后k条路,问你这k条路有几个交点,注意城市的序号其实就是一维坐标所在位置,所以就是两条平行的数轴,上面有点,而且之间有连线,问你有多少交点 一开始不好想把,这种题目也就排排序来试试看了,先对要修建的公路进行排序,然后再看这样是否可以更加方便的求出交点的数论,取路的左边点为先决条件从小到大排列,若相等则按照右边点来升序排列,然后以左边点为序号 和value值为1进行插入树状数组,先求出当前已经插入

poj 2892(二分+树状数组)

Tunnel Warfare Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 7749   Accepted: 3195 Description During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Generally sp

POJ 2352 Stars(树状数组 or 线段树)

链接: http://poj.org/problem?id=2352 题目大意: 在坐标上有n个星星,如果某个星星坐标为(x, y), 它的左下位置为:(x0,y0),x0<=x 且y0<=y.如果左下位置有a个星星,就表示这个星星属于level x 按照y递增,如果y相同则x递增的顺序给出n个星星,求出所有level水平的数量. 思路: 由于输入的顺序,对于第i颗星星,它的等级是之前输入的星星中,横坐标x小于等于i星横坐标的那些星星的总数量(前面的y一定比后面的y小). 所以是查询+更新操作

poj 2481 Cows 树状数组解法,详细解析。

Cows Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13445   Accepted: 4448 Description Farmer John's cows have discovered that the clover growing along the ridge of the hill (which we can think of as a one-dimensional number line) in hi