zoukankan      html  css  js  c++  java
  • HDU 5820 (可持久化线段树)

    Problem Lights (HDU 5820)

    题目大意

      在一个大小为50000*50000的矩形中,有n个路灯。(n<=500000)

      询问是否每一对路灯之间存在一条道路,使得长度为|x1 – x2| + |y1 – y2|且每个拐弯点都是路灯。

    解题分析

      官方题解:

         

      除了从左往右扫描一遍外,个人认为还需从右往左扫描一遍,记录右上方的点的信息。 实际实现时,只需将整个图左右对称翻转一下即可。

      学习了一下可持久化线段树的正确姿势。

      可持久化线段树的空间一定要开大,开大,开大。

      下图为模拟的小数据可持久化线段树的构造。

    参考程序

      1 #include <map>
      2 #include <set>
      3 #include <stack>
      4 #include <queue>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <string>
      8 #include <vector>
      9 #include <cstdio>
     10 #include <cstdlib>
     11 #include <cstring>
     12 #include <cassert>
     13 #include <iostream>
     14 #include <algorithm>
     15 #pragma comment(linker,"/STACK:102400000,102400000")
     16 using namespace std;
     17 
     18 #define N 1000008             
     19 #define M 50008    
     20 #define LL long long
     21 #define lson l,m,rt<<1
     22 #define rson m,r+1,rt<<1|1 
     23 #define clr(x,v) memset(x,v,sizeof(x));
     24 
     25 const int mo  = 1000000007;
     26 const int inf = 0x3f3f3f3f;
     27 const int INF = 2000000000;
     28 /**************************************************************************/ 
     29 struct node{
     30     int x,y;
     31     bool operator < (const node &b) const {
     32         return x<b.x || x==b.x && y<b.y;
     33     }
     34     node(int x=0,int y=0):x(x),y(y){}
     35 }a[N];
     36 int n,flag;
     37 map<pair<int,int>,int> Mpp;
     38 
     39 int mx[M],my[M];
     40 
     41 int cnt;
     42 int sum[N<<3],ls[N<<3],rs[N<<3];
     43 int root[M];
     44 
     45 void dfs(int rt,int l,int r){
     46     if (rt==0) return;
     47     printf("%d %d %d %d
    ",rt,l,r,sum[rt]);
     48     if (l==r) return;
     49     int m=(l+r)/2;
     50     dfs(ls[rt],l,m);
     51     dfs(rs[rt],m+1,r);
     52 }
     53 void debug(){
     54     printf("====================
    ");
     55     dfs(root[0],1,3);
     56     printf("
    ");
     57     dfs(root[1],1,3);
     58     printf("
    ");
     59     dfs(root[2],1,3);
     60     printf("
    ");
     61     dfs(root[3],1,3);
     62     printf("====================
    ");
     63 }
     64 void pushup(int rt){
     65     int l=ls[rt],r=rs[rt];
     66     sum[rt]=sum[l]+sum[r];
     67 }
     68 void build(int &rt,int l,int r){
     69     rt=++cnt;
     70     sum[rt]=0;
     71     if (l==r) return;
     72     int m=(l+r)/2;
     73     build(ls[rt],l,m);
     74     build(rs[rt],m+1,r);
     75     pushup(rt);
     76 }
     77 void update(int pos,int val,int x,int &y,int l,int r){
     78     y=++cnt;
     79     if (l==r){
     80         sum[y]=sum[x]+val;
     81         return;
     82     }
     83     ls[y]=ls[x]; rs[y]=rs[x];
     84     int m=(l+r)/2;
     85     if (pos <= m) update(pos,val,ls[x],ls[y],l,m);
     86     if (m  < pos) update(pos,val,rs[x],rs[y],m+1,r);
     87     pushup(y);
     88 }
     89 
     90 int query(int L,int R,int rt,int l,int r){
     91     if (L<=l && r<=R){
     92         return sum[rt];
     93     }
     94     int m=(l+r)/2;
     95     int res=0;
     96     if (L <= m) res+=query(L,R,ls[rt],l,m); 
     97     if (m <  R) res+=query(L,R,rs[rt],m+1,r);
     98     return res; 
     99 }
    100 
    101 void work1(){
    102     clr(mx,0); clr(my,0);
    103     cnt=0;         
    104     build(root[0],1,50000);
    105     int last=root[0];
    106     for (int i=1;i<=n;i++){
    107         int x1=a[i].x , y1=a[i].y;
    108         int x2=a[my[y1]].x , y2=a[mx[x1]].y;
    109         update(y1,1,last,root[x1],1,50000);
    110         int k1=query(y2+1,y1,root[x1],1,50000);
    111         int k2=query(y2+1,y1,root[x2],1,50000);
    112         if (k1!=k2+1) { flag=0; return; }
    113         mx[a[i].x]=i; my[a[i].y]=i; last=root[x1]; 
    114     }
    115 }
    116 
    117 int main(){
    118     int T;
    119     while (~scanf("%d",&n)){
    120         if (n==0) break;
    121          Mpp.clear();
    122         int num=0;
    123         for (int i=1;i<=n;i++){
    124             int x,y;
    125             scanf("%d %d",&x,&y);
    126             if (Mpp[make_pair(x,y)]==1){
    127                 num++;
    128             } 
    129             else
    130             {
    131                 Mpp[make_pair(x,y)]=1;
    132                 a[i-num].x=x;
    133                 a[i-num].y=y;
    134             }
    135         }
    136         n=n-num;
    137         sort(a+1,a+n+1);
    138         flag=1;
    139         work1(); 
    140         for (int i=1;i<=n;i++) a[i].x=50001-a[i].x;
    141         sort(a+1,a+n+1);
    142         work1();
    143         printf("%s
    ",flag ? "YES" : "NO" );
    144     }
    145 }
    146 /*
    147 5
    148 1 1
    149 1 2
    150 1 3
    151 2 1
    152 3 3
    153 */
    View Code
  • 相关阅读:
    springcloud生态图
    redis持久化机制之AOF与RDB
    关键字的理解
    Java IO6 :IO总结
    Java IO5:管道流、对象流
    Java IO4:字符流进阶及BufferedWriter、BufferedReader
    Java IO3:字节流
    Java IO2:RandomAccessFile
    Java IO1:IO和File
    java学习笔记
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/5755112.html
Copyright © 2011-2022 走看看