HDOJ6681Rikka with Cake(扫描线,线段树)
Posted myx12345
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ6681Rikka 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 ",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 ",ans+1); 202 203 204 } 205 206 return 0; 207 }
以上是关于HDOJ6681Rikka with Cake(扫描线,线段树)的主要内容,如果未能解决你的问题,请参考以下文章
HDOJ6686Rikka with Travels(树形DP)