码迷,mamicode.com
首页 > 其他好文 > 详细

Luogu P4246 [SHOI2008]堵塞的交通

时间:2020-01-18 21:25:46      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:turn   define   cst   while   r++   ace   put   char   c++   

线段树,维护6个关系。

技术图片

注意有可能出现这种情况:

技术图片

即虽然本身所在块两点时不连通的,但是可以依靠别的块贯通;于是有一些特判。

//c++14
#include<iostream>
#include<cstdio>
#include<bitset>
#define R register int
using namespace std;
namespace Luitaryi {
char B[1<<15],*S=B,*T=B;
#define getchar() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
inline int g() { R x=0,f=1;
  register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
  do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
} 
inline void g(char* str) {
    register char s; while(!isalpha(s=getchar()));
    do *str++=s; while(isalpha(s=getchar())); *str='\0';
}
const int N=100010;
int n; bool f[3][N];
struct node {
  mutable bitset<6> s;
  inline auto operator [] (int src) {return s[src];}
}t[N<<2];
#define ls (tr<<1)
#define rs (tr<<1|1)
inline void upd(node& p,node l,node r,int md) {
  p[0]=l[0]||(l[2]&&l[5]&&r[0]&&f[1][md]&&f[2][md]);
  p[1]=r[1]||(r[2]&&r[5]&&l[1]&&f[1][md]&&f[2][md]);
  p[2]=(l[2]&&r[2]&&f[1][md])||(l[3]&&r[4]&&f[2][md]);
  p[5]=(l[5]&&r[5]&&f[2][md])||(l[4]&&r[3]&&f[1][md]);
  p[3]=(l[2]&&r[3]&&f[1][md])||(l[3]&&r[5]&&f[2][md]);
  p[4]=(l[4]&&r[2]&&f[1][md])||(l[5]&&r[4]&&f[2][md]);
}
inline void build(int tr,int l,int r) {
  if(l==r) return t[tr][2]=t[tr][5]=1,void();
  R md=l+r>>1; build(ls,l,md),build(rs,md+1,r);
}
inline void change(int tr,int l,int r,int p,bool op) {
  if(l==r) return t[tr][0]=t[tr][1]=t[tr][3]=t[tr][4]=op,void(); 
  R md=l+r>>1; p<=md?change(ls,l,md,p,op):change(rs,md+1,r,p,op);
  upd(t[tr],t[ls],t[rs],md);
}
inline void change(int tr,int l,int r,int rw,int p,bool op) {
  R md=l+r>>1; if(md==p) 
    return f[rw][p]=op,upd(t[tr],t[ls],t[rs],md);
  p<=md?change(ls,l,md,rw,p,op):change(rs,md+1,r,rw,p,op);
  upd(t[tr],t[ls],t[rs],md);
}
inline node query(int tr,int l,int r,int LL,int RR) {
  if(LL<=l&&r<=RR) return t[tr]; R md=l+r>>1;
  if(RR<=md) return query(ls,l,md,LL,RR);
  if(LL>md) return query(rs,md+1,r,LL,RR); register node ret;
  return upd(ret,query(ls,l,md,LL,RR),query(rs,md+1,r,LL,RR),md),ret;
}
inline void main() {
  n=g(); build(1,1,n);
  register char s[6];
  R r1,r2,c1,c2,op; while(20040109) {
    g(s); if(s[0]=='E') break;
    r1=g(),c1=g(),r2=g(),c2=g();
    if(s[0]=='C') 
      if(r1==r2) change(1,1,n,r1,min(c1,c2),0);
      else change(1,1,n,c1,0);
    if(s[0]=='O') 
      if(r1==r2) change(1,1,n,r1,min(c1,c2),1);
      else change(1,1,n,c1,1);
    if(s[0]=='A') {
      if(c1>c2) swap(c1,c2),swap(r1,r2);
      register node l=query(1,1,n,1,c1),r=query(1,1,n,c2,n),md=query(1,1,n,c1,c2);
      if(r1==1&&r2==1) op=md[2]||(l[1]&&md[5]&&r[0])||(l[1]&&md[4])||(r[0]&&md[3]);
      if(r1==2&&r2==2) op=md[5]||(l[1]&&md[2]&&r[0])||(l[1]&&md[3])||(r[0]&&md[4]);
      if(r1==1&&r2==2) op=md[3]||(l[1]&&md[5])||(r[0]&&md[2])||(l[1]&&md[4]&&r[0]);
      if(r1==2&&r2==1) op=md[4]||(l[1]&&md[2])||(r[0]&&md[5])||(l[1]&&md[3]&&r[0]);
      putchar(op?'Y':'N'),putchar(10);
    }
  }
}
} signed main() {Luitaryi::main(); return 0;}

2020.01.18

Luogu P4246 [SHOI2008]堵塞的交通

标签:turn   define   cst   while   r++   ace   put   char   c++   

原文地址:https://www.cnblogs.com/Jackpei/p/12210114.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!