【POJ3067】Japan 线段树

题目描述

  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.

题目大意

  日本计划欢迎ACM ICPC世界总决赛和很多道路必须建的场馆。日本高岛与N在东海岸的城市和我的城市在西海岸(M ≤ 1000,n≤1000)。K高速公路将建。在每一个沿海城市,编号1,2,…从北到南。每个高速公路直线连接城市在东海岸和西海岸的城市。对于建设资金保证是ACM。总结的主要部分是由口岸之间的高速公路的数量确定。最多两高速公路交叉在一个位置。写一个程序,计算之间的高速公路的交叉数。

数据范围

M ≤ 1000,n≤1000

样例输入

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

样例输出

Test case 1: 5

解题思路

线段树水题!
对于一条边,以L为第一关键字,r为第二关键字排序,求r的逆序对个数。
还有就是会爆int。
虽然这很显然。

代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
using namespace std;
namespace IStream{const int LLL=1<<15;char buffer[LLL],*SSS,*TTT;char Get_Char(){if(SSS==TTT){TTT=(SSS=buffer)+fread(buffer,1,LLL,stdin);if(SSS==TTT) return EOF;}return *SSS++;}int Getint(){char c;int re=0,f=1;for(c=Get_Char();c<'0'||c>'9';c=Get_Char())if(c=='-')f=-1;while(c>='0'&&c<='9')re=(re<<1)+(re<<3)+(c-'0'),c=Get_Char();return re*f;}}class OStream{private:static const int LLL=1<<15;char staack[21];int topp;char buffer[LLL],*SSS;public:OStream(){SSS=buffer;}void Putint(int x,int flag){bool fl=false;if(flag==1) staack[++topp]=' ';if(flag==2) staack[++topp]='\n';if(x<0) x=-x,fl=true;if(!x) staack[++topp]='0';while(x)staack[++topp]=x%10+'0',x/=10;if(fl)staack[++topp]='-';while(topp){if(SSS==buffer+LLL-1){fwrite(buffer,1,SSS-buffer,stdout);SSS=buffer;}*SSS++=staack[topp--];}}~OStream(){fwrite(buffer,1,SSS-buffer,stdout);*SSS=0;}}os;
#ifndef ONLINE_JUDGE
inline int Getint(){int x=0,f=1;char ch=getchar();while('0'>ch||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
#else
using namespace IStream;
#endif
struct node{
    int L,r;
}w[1000005];
struct Seg{
    int L,r,Sum;
}Tree[400040];
bool cmp(node a,node b){
    return a.L<b.L||(a.L==b.L&&a.r<b.r);
}
void Build(int v,int L,int r){
    Tree[v]=(Seg){L,r,0};
    if(L==r)return;
    Build(2*v,L,(L+r)/2);
    Build(2*v+1,(L+r)/2+1,r);
}
int Ask(int v,int vl){
    if(Tree[v].r<vl)return 0;
    if(vl<=Tree[v].L)return Tree[v].Sum;
    return Ask(2*v,vl)+Ask(2*v+1,vl);
}
void Insert(int v,int vl){
    if(vl<Tree[v].L||Tree[v].r<vl)return;
    Tree[v].Sum++;
    Insert(v*2,vl);
    Insert(v*2+1,vl);
}
int main(){
    int Case=Getint();
    for(int orz=1;orz<=Case;orz++){
        int L=Getint(),r=Getint(),k=Getint();
        long long Ans=0;
        for(int i=1;i<=k;i++)w[i]=(node){Getint(),Getint()};
        sort(w+1,w+k+1,cmp);
        Build(1,1,1005);
        for(int i=1;i<=k;i++){
            Ans+=Ask(1,w[i].r+1);
            Insert(1,w[i].r);
        }
        cout<<"Test case "<<orz<<": "<<Ans<<"\n";
    }
    return 0;
}

转载于:https://www.cnblogs.com/Cedric341561/p/6811027.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值