「NOI2017」游戏

\(d\)这么小,你考虑直接对\(d\)个东西暴力

枚举\(x\)为\(a\)或\(b\)(\(c\)就不用了,因为\(a,b\)已经包含\(c\))了,剩下的就是个\(2-sat\)问题了

但是你发现有个情况是,在若\(A\)即\(B\)时,如果\(B\)被\(ban\)了,那么\(A\)也要被\(ban\)

我们记录一下被\(ban\)的点,然后在球方案的时候判一下(不得不用topo排序了..

但是其实也可以\(A\)连\(\lnot A\),就可以直接比较SCC编号大小搞方案了


Code:

#include <cstdio>
#include <cctype>
#include <cstring>
#include <vector>
#include <algorithm>
using std::min;
const int SIZE=1<<21;
char ibuf[SIZE],*iS,*iT;
//#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++)
#define gc() getchar()
template <class T>
void read(T &x)
{
x=0;char c=gc();
while(!isdigit(c)) c=gc();
while(isdigit(c)) x=x*10+c-'0',c=gc();
}
template <class T>
void reads(T &x)
{
char c=gc();
while(c<'a'||c>'z') c=gc();
x=c-'a'+1;
}
template <class T>
void readb(T &x)
{
char c=gc();
while(c<'A'||c>'Z') c=gc();
x=c-'A'+1;
}
const int N=2e5+10;
int head[N],to[N],Next[N],cnt;
void add(int u,int v)
{
to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
}
struct _toki
{
int a,b,c,d;
}toki[N];
int n,m,_n,yuu[N][4],ops[N],saki[N];
int val[N],ban[N],Ban[N],q[N],bel[N],opsi[N];
int low[N],dfn[N],in[N],sta[N],tot,dfsclock;
std::vector <int> E[N];
void tarjan(int now)
{
dfn[now]=low[now]=++dfsclock;
in[sta[++tot]=now]=1;
for(int v,i=head[now];i;i=Next[i])
{
if(!dfn[v=to[i]])
{
tarjan(v);
low[now]=min(low[now],low[v]);
}
else if(in[v])
low[now]=min(low[now],dfn[v]);
}
if(low[now]==dfn[now])
{
int k;++_n;
do
{
k=sta[tot--];
in[k]=0;
bel[k]=_n;
}while(now!=k);
}
}
int solve()
{
memset(head,0,sizeof head);cnt=0;
memset(ban,0,sizeof ban);
memset(Ban,0,sizeof Ban);
for(int a,b,c,d,i=1;i<=m;i++)
{
a=toki[i].a,b=toki[i].b,c=toki[i].c,d=toki[i].d;
if(saki[a]==b) continue;
if(saki[c]==d)
{
ban[yuu[a][b]]=1;
continue;
}
add(yuu[a][b],yuu[c][d]);
add(ops[yuu[c][d]],ops[yuu[a][b]]);
}
memset(in,0,sizeof in);
memset(dfn,0,sizeof dfn);
memset(low,0,sizeof low);
memset(bel,0,sizeof bel);
memset(opsi,0,sizeof opsi);
_n=dfsclock=0;
for(int i=1;i<=n<<1;i++)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=n;i++)
if(bel[i]==bel[i+n])
return -1;
memset(val,-1,sizeof val);
for(int i=1;i<=_n;i++) E[i].clear();
//int ecnt=0;
for(int u=1;u<=n<<1;u++)
{
for(int v,i=head[u];i;i=Next[i])
if(bel[u]!=bel[v=to[i]])
E[bel[v]].push_back(bel[u]),++in[bel[u]];//++ecnt;
Ban[bel[u]]|=ban[u];
opsi[bel[u]]=bel[ops[u]];
}
int l=1,r=0;
for(int i=1;i<=_n;i++)
if(!in[i]&&!Ban[i])
q[++r]=i;
while(l<=r)
{
int now=q[l++];
if(val[now]==-1) val[now]=0,val[opsi[now]]=1;
for(int v,i=0;i<E[now].size();i++)
{
v=E[now][i];
--in[v];
if(!in[v]&&!Ban[v]) q[++r]=v;
}
}
for(int i=1;i<=n;i++)
if(val[bel[i]]==-1)
return -1;
for(int i=1;i<=n;i++)
{
int x=val[bel[i]];
for(int j=1;j<=3;j++)
{
if(saki[i]!=j)
{
if(!x) putchar('A'+j-1);
--x;
}
}
//puts("");
}
return 0;
}
int main()
{
//freopen("game.in","r",stdin);
//freopen("game.out","w",stdout);
int d,yuy[10];
read(n),read(d);
d=0;
for(int i=1;i<=n;i++)
{
ops[i]=i+n;
ops[i+n]=i;
reads(saki[i]);
if(saki[i]==24)
{
yuy[++d]=i;
continue;
}
int aya=i;
for(int j=1;j<=3;j++)
{
if(saki[i]!=j)
{
yuu[i][j]=aya;
aya+=n;
}
}
}
read(m);
for(int i=1;i<=m;i++) read(toki[i].a),readb(toki[i].b),read(toki[i].c),readb(toki[i].d);
if(!d)
{
if(solve()==-1) puts("-1");
return 0;
}
for(int s=0;s<1<<d;s++)
{
for(int i=1;i<=d;i++)
{
if(!(s>>i-1&1))
{
saki[yuy[i]]=1;
yuu[yuy[i]][2]=yuy[i];
yuu[yuy[i]][3]=yuy[i]+n;
}
else
{
yuu[yuy[i]][1]=yuy[i];
saki[yuy[i]]=2;
yuu[yuy[i]][3]=yuy[i]+n;
}
}
if(~solve()) return 0;
}
puts("-1");
return 0;
}

2019.6.2

「NOI2017」游戏 解题报告的更多相关文章

  1. 「NOI2017」蔬菜 解题报告

    「NOI2017」蔬菜 首先考虑流 可以从 \(s\) 流入表示得到蔬菜,流出到 \(t\) 表示卖出蔬菜,给每个蔬菜拆点,并给它它每天应得的蔬菜. 但是我们没办法直接给,注意到如果把变质看成得到并可 ...

  2. 「NOI2017」整数 解题报告

    「NOI2017」整数 有一些比较简单的\(\log^2n\)做法 比如暴力在动态开点线段树上维护每个位置为\(0\)还是\(1\),我们发现涉及到某一位加上\(1\)或者减去\(1\)实际上对其他位 ...

  3. 「NOI2017」游戏

    「NOI2017」游戏 题目描述 小 L 计划进行 \(n\) 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 \(A\).\(B\).\ ...

  4. LOJ_2305_「NOI2017」游戏 _2-sat

    LOJ_2305_「NOI2017」游戏 _2-sat 题意: 给你一个长度为n的字符串S,其中第i个字符为a表示第i个地图只能用B,C两种赛车,为b表示第i个地图只能用A,C两种赛车,为c表示第i个 ...

  5. loj #2305. 「NOI2017」游戏

    #2305. 「NOI2017」游戏 题目描述 小 L 计划进行 nnn 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 AAA.BBB. ...

  6. LOJ2305 「NOI2017」游戏

    「NOI2017」游戏 题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行$n$场 ...

  7. 「ZJOI2016」旅行者 解题报告

    「ZJOI2016」旅行者 对网格图进行分治. 每次从中间选一列,然后枚举每个这一列的格子作为起点跑最短路,进入子矩形时把询问划分一下,有点类似整体二分 至于复杂度么,我不会阿 Code: #incl ...

  8. 「HNOI2016」树 解题报告

    「HNOI2016」树 事毒瘤题... 我一开始以为每次把大树的子树再接给大树,然后死活不知道咋做,心想怕不是个神仙题哦 然后看题解后才发现是把模板树的子树给大树,虽然思维上难度没啥了,但是还是很难写 ...

  9. 「HNOI2016」序列 解题报告

    「HNOI2016」序列 有一些高妙的做法,懒得看 考虑莫队,考虑莫队咋移动区间 然后你在区间内部找一个最小值的位置,假设现在从右边加 最小值左边区间显然可以\(O(1)\),最小值右边的区间是断掉的 ...

随机推荐

  1. 【bzoj1458】士兵占领(最大流||有源汇最大流)

    转载 http://hzwer.com/2963.html Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里 ...

  2. Outlets

    Outlets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  3. R中unlist函数的使用

    买的书里面实例讲的不清不楚,所以看帮助文档了 用法:unlist(x, recursive = TRUE, use.names = TRUE) 帮助文档讲x可以是向量或者列表,如果是向量,则原样返回, ...

  4. php 统计每天价格,货币种类,汇总得算法和数据处理 (后端和前段实现自动统计价格和币种类型)

    整体实现逻辑介绍 1.对查询数据做一个总体查询,需要根据查询自己主要业务逻辑数据. 2.对总体查询数据和时间和币种类型做三部分数据处理. 3.总体查询数据按照币种和日期组装二维数据对应得键值是价格. ...

  5. JDK1.8中ArrayList的实现原理及源码分析

    一.概述 ArrayList是Java开发中使用比较频繁的一个类,通过对源码的解读,可以了解ArrayList的内部结构以及实现方法,清楚它的优缺点,以便我们在编程时灵活运用. 二.源码分析 2.1 ...

  6. python中将12345转换为'12345',不要使用str

    a = 12345 #创建一个空字符串 ret = "" #whlie循环,条件为当a为true时,即a不是 0的时候 while a : #定义一个变量,对a求余 last = ...

  7. Docker容器数据卷-Volume详解

    Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中称为数据卷(Data Volume).数据卷可以用来存储Docker应用的数据,也可以用来在Docker容器间进行数据共享.数据 ...

  8. java继承方法覆盖

    public class TestB { private void f() { System.out.println("TestB"); } public static void ...

  9. Java学习之线程通信(多线程(synchronized))--生产者消费者

    分析线程经典案例生产者消费者 /** 共享数据 */ class Resource { private String name; private int count=1; private boolea ...

  10. 终于好了 ipython 里执行dos命令 显示结果却显示在kernel界面里 搞定了

    import os cmd = r'type c:\foo.txt' os.system(cmd) import os cmd = r'type c:\foo.txt' os.system(cmd) ...