POJ3067(树状数组:统计数字出现个数)

Japan

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 24151   Accepted: 6535

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 on the West coast (M <= 1000, N <= 1000). K superhighways will be build. Cities on each coast are numbered 1, 2, ... from North to South. Each superhighway is straight line and connects city on the East coast with city of the West coast. The funding for the construction is guaranteed by ACM. A major portion of the sum is determined by the number of crossings between superhighways. At most two superhighways cross at one location. Write a program that calculates the number of the crossings between superhighways.

Input

The input file starts with T - the number of test cases. Each test case starts with three numbers – N, M, K. Each of the next K lines contains two numbers – the numbers of cities connected by the superhighway. The first one is the number of the city on the East coast and second one is the number of the city of the West coast.

Output

For each test case write one line on the standard output: 
Test case (case number): (number of crossings)

Sample Input

1
3 4 4
1 4
2 3
3 2
3 1

Sample Output

Test case 1: 5题意:两列数字连线,统计线段交叉的产生的点数(交于同一个数字的不算)
#include"cstdio"
#include"cstring"
#include"algorithm"
using namespace std;
const int MAXN=1000005;
struct Node{
    int west,east;
}hways[MAXN];
bool comp(const Node &a,const Node &b)
{
    if(a.east != b.east)    return a.east > b.east;
    else return a.west > b.west;
}

int bit[MAXN];
void add(int i,int x)
{
    while(i<MAXN)
    {
        bit[i]+=x;
        i+=i&(-i);
    }
}

long long sum(int i)
{
    long long s=0;
    while(i>0)
    {
        s+=bit[i];
        i-=i&(-i);
    }
    return s;
}

int main()
{
    int T;
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++)
    {
        memset(bit,0,sizeof(bit));
        long long ans=0;
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<k;i++)
        {
            scanf("%d%d",&hways[i].east,&hways[i].west);
        }
        sort(hways,hways+k,comp);
        add(hways[0].west,1);
        for(int i=1;i<k;i++)
        {
            ans+=sum(hways[i].west-1);
            add(hways[i].west,1);
        }

        printf("Test case %d: %I64d\n",cas,ans);
    }

    return 0;
}
时间: 2024-10-11 16:52:52

POJ3067(树状数组:统计数字出现个数)的相关文章

POJ2481(树状数组:统计数字 出现个数)

Cows Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 15405   Accepted: 5133 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

poj Ping pong LA 4329 (树状数组统计数目)

Ping pong Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2302   Accepted: 879 Description N(3<=N<=20000) ping pong players live along a west-east street(consider the street as a line segment). Each player has a unique skill rank. To im

POJ3067 树状数组+逆序数

设两线段为(x1,y1) ,(x2,y2), 若使两线段相交,需使x1<x2&&y1>y2||x1>x2&&y1<y2. 那么本题就变得很简单了,对东边点x从小到大排序,当x相等时对西边点y从小到大排序,每插入一条线段,就求一下逆序对数.总和即为答案. 代码如下: 1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #define

4.4 省选模拟赛 拉格朗日计数 树状数组+容斥.

像这种计数 问题什么的 是最讨厌的了... 考虑是环往环后面再续一段 暴力枚举前两个数字 树状数组统计第三个数的个数 n^2log. 考虑只枚举第个数 发现由于边界问题什么的很难处理. 再将枚举直接放到环上 发现边界问题没有了 不过存在 枚举第二个数之后 有 123 231 312 这三种形式. 第一种形式很好统计 预处理一下左边有多少个数字比自己小即可. 考虑第二种和第三种形式 很难在枚举2的时候统计出来这两种形式 考虑容斥 231=XX1-321. 312=3XX-321. 发现XX1和3X

codeforeces 540E(树状数组

题意:交换自然数中的若干对数,求交换后总共有多少逆序数对. 思路:因为题目数字范围比较大,不能直接用树状数组算,首先要离散化.然后一种算法是官方题解中根据逆序对数是否属于交换过的数分类讨论统计.我的算法是把没有交换的连续的数看成一个数,使用树状数组统计的时候直接加上这个区间的数字个数,这样就不需要繁琐(?)的讨论了. #include<iostream> #include<map> #include<algorithm> #include<cstdio> #

UVA1406 - A Sequence of Numbers(树状数组)

题目链接 题目大意: 给定N个数字,给两种操作:C x: 把这N个数字都加上x.Q x:查询这N个数里面有多少个数字和2^x取且大于0.最后把每个查询的结果求和作为答案. 解题思路: 查询与2^x取且为1,那么就意味这那个符合要求的数的第x位要是1. 但是这里还有全部加上x的操作,可以用一个变量来记录所有C操作的x的和.有这个加数的话,第x位为1的可能可以通过低位进位得到,所以这里开16个树状数组,第i个树状数组存放的是每个数从低位开始,连续的i位的值.例如7:第0个树状数组就加上1, 第1个树

FZOJ 2245 动态树(离散+离线+ 树状数组)

Problem 2245 动态树 Accept: 17    Submit: 82Time Limit: 3000 mSec    Memory Limit : 65536 KB  Problem Description YellowStar拥有一棵神奇的动态树,该树由n个带权结点,n-1条边构成,任意两个结点互相可达,标号为i结点的权值为Wi. 由于物质是运动的,这棵树每天都会发生一些变化,在第i天,该树权值在[l,r]的结点会发出强烈的光芒,YellowStar看到这一现象会非常的愉悦,它的

BZOJ2683: 简单题(CDQ分治 + 树状数组)

BZOJ2683: 简单题(CDQ分治 + 树状数组) 题意: 你有一个\(N*N\)的棋盘,每个格子内有一个整数,初始时的时候全部为\(0\),现在需要维护两种操作: 命令 参数限制 内容 \(1\ x\ y\ A\) \(1\le x,y \le N\),A是正整数 将格子\(x,y\)里的数字加上\(A\) \(2\ x1\ y1\ x2\ y2\) \(1\le x1\le x2\le N,1\le y1\le y2\le N\) 输出\(x1\ y1\ x2\ y2\)这个矩形内的数字

UVA 11990 ”Dynamic“ Inversion(线段树+树状数组)

[题目链接] UVA11990 [题目大意] 给出一个数列,每次删去一个数,求一个数删去之前整个数列的逆序对数. [题解] 一开始可以用树状数组统计出现的逆序对数量 对于每个删去的数,我们可以用线段树求出它在原序列中的逆序对贡献 在线段树的每个区间有序化数据,就可以二分查找出这个数在每个区间的位置, 这样就处理出了划分出的区间的贡献,先用答案减去这一部分 接下来考虑已经删去部分的容斥,我们发现只要对删去部分再做一次类似的操作, 将这一部分跟当前删去数求一次贡献就是刚才多减去的部分,将这部分的答案