枚举最后光线射到终点的方向,求出从起点出发以及从终点出发的光路,扫描线+树状数组统计交点个数即可。

注意当光路成环时,对应的两个方向应该只算一次。

时间复杂度$O(n\log n)$。

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100010;
const ll inf=1LL<<50;
inline void read(int&a){
char c;bool f=0;a=0;
while(!((((c=getchar())>='0')&&(c<='9'))||(c=='-')));
if(c!='-')a=c-'0';else f=1;
while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';
if(f)a=-a;
}
int n,i,j,k,q[N],g[N][4],dx[4]={0,0,-1,1},dy[4]={-1,1,0,0};char d[N],w[N*2];
int cb,cc,ce,cf,bit[N*6];ll f[N*6],ans;
struct P{
ll x,y;
P(){}
P(ll _x,ll _y){x=_x,y=_y;}
void read(){
int a,b;
::read(a),::read(b);
x=a,y=b;
}
}B,a[N],b[N*2],c[N*2];
struct E{
ll x,l,r;int t;
E(){}
E(ll _x,ll _l,ll _r,int _t){x=_x,l=_l,r=_r,t=_t;}
}e[N*6];
inline bool cmpx(int x,int y){return a[x].x==a[y].x?a[x].y<a[y].y:a[x].x<a[y].x;}
inline bool cmpy(int x,int y){return a[x].y==a[y].y?a[x].x<a[y].x:a[x].y<a[y].y;}
inline bool cmpe(const E&a,const E&b){return a.x==b.x?a.t>b.t:a.x<b.x;}
int work(P o,int k,P*q,int&m){
q[m=1]=o;
int i,j=-1;ll dis;
for(i=0;i<=n;i++){
if(k==0&&!(a[i].x==o.x&&a[i].y<=o.y))continue;
if(k==1&&!(a[i].x==o.x&&a[i].y>=o.y))continue;
if(k==2&&!(a[i].y==o.y&&a[i].x<=o.x))continue;
if(k==3&&!(a[i].y==o.y&&a[i].x>=o.x))continue;
ll t=1LL*abs(a[i].x-o.x)+1LL*abs(a[i].y-o.y);
if(!t)continue;
if(j<0||t<dis)j=i,dis=t;
}
while(~j){
q[++m]=a[j];
w[m]=k;
if(!j)return 2;
if(m>2&&q[m].x==q[2].x&&q[m].y==q[2].y&&w[m]==w[2])return 1;
if(d[j]=='/')k=(k+2)&3;else k=3-k;
o=a[j];
j=g[j][k];
}
q[++m]=o;
q[m].x+=inf*dx[k];
q[m].y+=inf*dy[k];
return 2;
}
inline void adda(const P&A,const P&B){
if(A.y!=B.y)return;
ll l=A.x,r=B.x;
if(l>r)swap(l,r);
l++,r--;
if(l>r)return;
e[++ce]=E(l,A.y,0,1);
e[++ce]=E(r,A.y,0,-1);
f[++cf]=A.y;
}
inline void addb(const P&A,const P&B){
if(A.x!=B.x)return;
ll l=A.y,r=B.y;
if(l>r)swap(l,r);
l++,r--;
if(l>r)return;
e[++ce]=E(A.x,l,r,0);
f[++cf]=l,f[++cf]=r;
}
inline int lower(ll x){
int l=1,r=cf,mid,t;
while(l<=r)if(f[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
return t;
}
inline void add(int x,int p){for(;x<=cf;x+=x&-x)bit[x]+=p;}
inline int ask(int x){int t=0;for(;x;x-=x&-x)t+=bit[x];return t;}
ll cal(){
int i;
sort(f+1,f+cf+1);
for(i=1;i<=cf;i++)bit[i]=0;
sort(e+1,e+ce+1,cmpe);
ll ret=0;
for(i=1;i<=ce;i++)if(e[i].t)add(lower(e[i].l),e[i].t);else ret+=ask(lower(e[i].r))-ask(lower(e[i].l)-1);
return ret;
}
ll solve(int x){
int i;
ce=cf=0;
for(i=1;i<cb;i++)adda(b[i],b[i+1]);
for(i=3-x;i<cc;i++)addb(c[i],c[i+1]);
ll ret=cal();
ce=cf=0;
for(i=1;i<cb;i++)addb(b[i],b[i+1]);
for(i=3-x;i<cc;i++)adda(c[i],c[i+1]);
return ret+cal();
}
int main(){
read(n);
B.read();
for(i=1;i<=n;i++){
char c[9];
a[i].read();
scanf("%s",c);
d[i]=c[0];
q[i]=i;
}
sort(q,q+n+1,cmpx);
for(i=0;i<=n;i++)for(j=0;j<4;j++)g[i][j]=-1;
for(i=0;i<=n;){
for(j=i;j<=n&&a[q[i]].x==a[q[j]].x;j++);
for(i++;i<j;i++){
g[q[i]][0]=q[i-1];
g[q[i-1]][1]=q[i];
}
}
sort(q,q+n+1,cmpy);
for(i=0;i<=n;){
for(j=i;j<=n&&a[q[i]].y==a[q[j]].y;j++);
for(i++;i<j;i++){
g[q[i]][2]=q[i-1];
g[q[i-1]][3]=q[i];
}
}
work(P(0,0),1,b,cb);
for(i=0;i<4;i++){
int x=work(B,i,c,cc);
ans+=solve(x)*x;
}
return printf("%lld",ans/2),0;
}

  

BZOJ3536 : [Usaco2014 Open]Cow Optics的更多相关文章

  1. BZOJ 3446: [Usaco2014 Feb]Cow Decathlon( 状压dp )

    水状压dp. dp(x, s) = max{ dp( x - 1, s - {h} ) } + 奖励(假如拿到的) (h∈s). 时间复杂度O(n * 2^n) ------------------- ...

  2. 3893: [Usaco2014 Dec]Cow Jog

    3893: [Usaco2014 Dec]Cow Jog Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 174  Solved: 87[Submit] ...

  3. bzoj3446[Usaco2014 Feb]Cow Decathlon*

    bzoj3446[Usaco2014 Feb]Cow Decathlon 题意: FJ有n头奶牛.FJ提供n种不同的技能供奶牛们学习,每头奶牛只能学习一门技能,每门技能都要有奶牛学习. 第i头奶牛学习 ...

  4. [Usaco2014 Open Gold ]Cow Optics (树状数组+扫描线/函数式线段树)

    这道题一上手就知道怎么做了= = 直接求出原光路和从目标点出发的光路,求这些光路的交点就行了 然后用树状数组+扫描线或函数式线段树就能过了= = 大量的离散+模拟+二分什么的特别恶心,考试的时候是想到 ...

  5. [bzoj3893][Usaco2014 Dec]Cow Jog_暴力

    Cow Jog bzoj-3893 Usaco-2014 Dec 题目大意:题目链接. 注释:略. 想法: 先按照坐标排序. 我们发现每个牛只会被后面的牛影响. 所以我们考虑逆向枚举. 记录一下i+1 ...

  6. Bzoj3893 [Usaco2014 Dec]Cow Jog

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 302  Solved: 157 Description The cows are out exerci ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. BZOJ-USACO被虐记

    bzoj上的usaco题目还是很好的(我被虐的很惨. 有必要总结整理一下. 1592: [Usaco2008 Feb]Making the Grade 路面修整 一开始没有想到离散化.然后离散化之后就 ...

  9. BZOJ3476 : [Usaco2014 Mar]The Lazy Cow

    旋转坐标系后转化为正方形,$x'=x+y$,$y'=x-y+1000001$,$k'=2k-1$ 两根扫描线从左往右扫 f[i]表示y坐标下边界为i时的价值和 每次加入/删除一个点等价于一段区间加减 ...

随机推荐

  1. Py学生信息管理系统 案例(优化版)

    # 第一题:设计一个全局变量,来保存很多个学生信息:学生(学号, 姓名,年龄):思考要用怎样的结构来保存:# 第二题:在第一题基础上,完成:让用户输入一个新的学生信息(学号,姓名,年龄):你将其保存在 ...

  2. java.io几种读写文件的方式

    一.Java把这些不同来源和目标的数据都统一抽象为数据流. Java语言的输入输出功能是十分强大而灵活的. 在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作 ...

  3. Django目录结构分析

    Django目录结构分析: Django的Linux项目目录记录 [root@cmdb Django]# tree mysite mysite ├── cmdb │   ├── admin.py # ...

  4. [转]scp、sftp命令使用

    http://wangxuedong.com/index.php/archives/182/ 前言 有时候想上传文件到服务器或者从服务器下载一个文件到本地,但是服务器还没有配置ftp等环境,这时候可以 ...

  5. 【AtCoder】Tenka1 Programmer Contest 2019

    Tenka1 Programmer Contest 2019 C - Stones 题面大意:有一个01序列,改变一个位置上的值花费1,问变成没有0在1右边的序列花费最少多少 直接枚举前i个都变成0即 ...

  6. markdown 语法小结

    1 标题 # 一级标题 ## 二级标题 2  字体加粗和斜体 *斜体* **加粗** 3.引用 > 4.换行 空行 或两个空格+tab 5.无序列表 + 第一个 + 第二个 - 第一个 - 第二 ...

  7. bash: cannot create temp file for here-document: Read-only file system

    文件系统被强制只读问题,第一眼看到百度了一下,说可能磁盘坏了.卧槽我都吓懵了系统盘坏了,闹着玩呢,然后接着查资料,排查 mount 查看所有挂载,发现根目录的挂载权限是ro只读. /dev/sda2 ...

  8. pip安装其他包报错

    pip安装时报错  Unknown or unsupported command 'install 一.是否配置了路径 配置了看下面的方法. 二.有多个pip系统不知道调用哪个. 1.where pi ...

  9. BZOJ2527 [Poi2011]Meteors 整体二分 树状数组

    原文链接http://www.cnblogs.com/zhouzhendong/p/8686460.html 题目传送门 - BZOJ2527 题意 有$n$个国家. 太空里有$m$个太空站排成一个圆 ...

  10. HDU4185 Oil Skimming 二分图匹配 匈牙利算法

    原文链接http://www.cnblogs.com/zhouzhendong/p/8231146.html 题目传送门 - HDU4185 题意概括 每次恰好覆盖相邻的两个#,不能重复,求最大覆盖次 ...