【HDOJ6681】Rikka with Cake(扫描线,线段树)

题意:给定一个n*m的平面,有k条垂直或平行的直线,问将平面分成了几个互不联通的部分

n,m<=1e9,k<=1e5

思路:

刻在DNA里的二维数点

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 #define N  410000
 11 #define M  4100000
 12 #define fi first
 13 #define se second
 14 #define MP make_pair
 15 #define pi acos(-1)
 16 #define mem(a,b) memset(a,b,sizeof(a))
 17 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 18 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 19 #define lowbit(x) x&(-x)
 20 #define Rand (rand()*(1<<16)+rand())
 21 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 22 #define ls p<<1
 23 #define rs p<<1|1
 24
 25 const ll MOD=1e9+7,inv2=(MOD+1)/2;
 26       double eps=1e-6;
 27       int INF=1e9;
 28       int da[4]={-1,1,0,0};
 29       int db[4]={0,0,-1,1};
 30
 31 char ch[N][2];
 32 int t[N<<2],x[N],y[N],c[N],p;
 33
 34 struct arr1
 35 {
 36     int t,x,y;
 37 }a[N];
 38
 39 bool cmp1(arr1 a,arr1 b)
 40 {
 41     return a.t<b.t;
 42 }
 43
 44 struct arr2
 45 {
 46     int x1,x2,y;
 47 }b[N];
 48
 49 bool cmp2(arr2 a,arr2 b)
 50 {
 51     return a.y<b.y;
 52 }
 53
 54 int read()
 55 {
 56    int v=0,f=1;
 57    char c=getchar();
 58    while(c<48||57<c) {if(c==‘-‘) f=-1; c=getchar();}
 59    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 60    return v*f;
 61 }
 62
 63 int lisan(int x)
 64 {
 65     int l=1,r=p,last=1;
 66     while(l<=r)
 67     {
 68         int mid=(l+r)>>1;
 69         if(c[mid]>x) r=mid-1;
 70         if(c[mid]==x){last=mid; r=mid-1;}
 71         if(c[mid]<x) l=mid+1;
 72     }
 73     return last;
 74 }
 75
 76 void build(int l,int r,int p)
 77 {
 78     t[p]=0;
 79     if(l==r) return;
 80     int mid=(l+r)>>1;
 81     build(l,mid,ls);
 82     build(mid+1,r,rs);
 83 }
 84
 85 int query(int l,int r,int x,int y,int p)
 86 {
 87     if(x<=l&&r<=y) return t[p];
 88     int mid=(l+r)>>1;
 89     int s=0;
 90     if(x<=mid) s+=query(l,mid,x,y,ls);
 91     if(y>mid) s+=query(mid+1,r,x,y,rs);
 92     return s;
 93 }
 94
 95 void update(int l,int r,int x,int v,int p)
 96 {
 97     if(l==r)
 98     {
 99         t[p]+=v;
100         return;
101     }
102     int mid=(l+r)>>1;
103     if(x<=mid) update(l,mid,x,v,ls);
104      else update(mid+1,r,x,v,rs);
105     t[p]=t[ls]+t[rs];
106 }
107
108 int main()
109 {
110     //freopen("1.in","r",stdin);
111     //freopen("1.out","w",stdout);
112
113     int cas;
114     scanf("%d",&cas);
115
116     while(cas--)
117     {
118         int n=read(),m=read(),K=read();
119         ll ans=0;
120         int m1=0,m2=0;
121         p=0;
122         rep(i,1,K)
123         {
124             x[i]=read(),y[i]=read();
125             scanf("%s",ch[i]+1);
126             //if(ch[i][1]==‘U‘&&y[i]==) ans++;
127             //if(ch[i][1]==‘R‘&&x[i]==1) ans++;
128             c[++p]=x[i];
129             c[++p]=y[i];
130         }
131         //printf("ans=%I64d\n",ans);
132         c[++p]=n;
133         c[++p]=m;
134         c[++p]=1;
135         sort(c+1,c+p+1);
136         rep(i,1,K)
137         {
138             x[i]=lisan(x[i]);
139             y[i]=lisan(y[i]);
140         }
141         n=lisan(n),m=lisan(m);
142         rep(i,1,K)
143         {
144             if(ch[i][1]==‘U‘)
145             {
146                 m1++;
147                 a[m1].t=y[i];
148                 a[m1].x=x[i];
149                 a[m1].y=1;
150                 //a[m1].x=x[i];
151                 //a[m1].y1=y[i];
152                 //a[m1].y2=m;
153             }
154             if(ch[i][1]==‘D‘)
155             {
156                 m1++;
157                 a[m1].t=1;
158                 a[m1].x=x[i];
159                 a[m1].y=1;
160
161                 m1++;
162                 a[m1].t=y[i]+1;
163                 a[m1].x=x[i];
164                 a[m1].y=-1;
165                 //a[m1].x=x[i];
166                 //a[m1].y1=1;
167                 //a[m1].y2=y[i];
168             }
169             if(ch[i][1]==‘L‘)
170             {
171                 m2++;
172                 b[m2].x1=1;
173                 b[m2].x2=x[i];
174                 b[m2].y=y[i];
175             }
176             if(ch[i][1]==‘R‘)
177             {
178                 m2++;
179                 b[m2].x1=x[i];
180                 b[m2].x2=n;
181                 b[m2].y=y[i];
182             }
183         }
184         sort(a+1,a+m1+1,cmp1);
185         sort(b+1,b+m2+1,cmp2);
186         build(1,p,1);
187         int j1=1,j2=1;
188         rep(i,1,p)
189         {
190             while(j1<=m1&&a[j1].t==i)
191             {
192                 update(1,p,a[j1].x,a[j1].y,1);
193                 j1++;
194             }
195             while(j2<=m2&&b[j2].y==i)
196             {
197                 ans+=query(1,p,b[j2].x1,b[j2].x2,1);
198                 j2++;
199             }
200         }
201         printf("%I64d\n",ans+1);
202
203
204     }
205
206     return 0;
207 }

原文地址:https://www.cnblogs.com/myx12345/p/11666961.html

时间: 2024-10-22 15:00:42

【HDOJ6681】Rikka with Cake(扫描线,线段树)的相关文章

hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积

题目链接:点击打开链接 题目描写叙述:给定一些矩形,求这些矩形的总面积.假设有重叠.仅仅算一次 解题思路:扫描线+线段树+离散(代码从上往下扫描) 代码: #include<cstdio> #include <algorithm> #define MAXN 110 #define LL ((rt<<1)+1) #define RR ((rt<<1)+2) using namespace std; int n; struct segment{ double l

POJ训练计划1177_Picture(扫描线/线段树+离散)

解题报告 题意: 求矩形周长和. 思路: 左扫上扫,扫过了. #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; struct Seg { int lx,rx,ly,ry,h,v; friend bool operator < (Seg a,Seg b) { re

POJ 1151 Atlantis 扫描线+线段树

点击打开链接 Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17252   Accepted: 6567 Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of pa

poj 1151 Atlantis (离散化 + 扫描线 + 线段树)

题目链接题意:给定n个矩形,求面积并,分别给矩形左上角的坐标和右上角的坐标. 分析: 1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include <cstdlib> 6 #include <algorithm> 7 #define LL __int64 8 #define lson l, mid, 2*rt

HDU3265_Posters(扫描线/线段树)

解题报告 题意: 给定的矩形里面有镂空的矩阵,求矩阵面积并. 思路: 直接把一个图形拆成4个矩形,进行面积并. 扫描线+线段树 #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #define LL __int64 using namespace std; struct Seg { int lx,rx,h,v; friend bool operator

HDU1377_Counting Squares(扫描线/线段树)

解题报告 题意: 矩形面积并. 思路: 扫描线+线段树 #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; struct Seg { int lx,rx,h,v; friend bool operator < (Seg a,Seg b) { return a.h<b.h; } } seg[500000]

HDU1542_Atlantis(扫描线/线段树+离散)

解题报告 题目传送门 题意: 求矩形并面积. 思路: 离散+线段树+扫描线. #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; struct Seg { int v; double h,lx,rx; friend bool operator < (Seg a,Seg b) { return a.h<b

【HDU 5828】Rikka with Sequence(线段树)

[HDU 5828]Rikka with Sequence(线段树) Rikka with Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2311    Accepted Submission(s): 391 Problem Description As we know, Rikka is poor at math.

HDU 1255 覆盖的面积 (扫描线 线段树 离散化)

题目链接 题意:中文题意. 分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt>=0改成cnt>=2就行了,. 但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了,因为虽然现在都不等于 2,但是之前的那个线段加上现在的已经覆盖2次了. 1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include &

HNU12884_Area Coverage(扫描线/线段树+离散化)

解题报告 题目传送门 题意: 又是求面积并 思路: 又是求面积并,还被坑了,题目明明描述的是int坐标,用了double才过... #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; struct Seg { double lx,rx,h; int v; friend bool operator <(Seg