「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. sql 连接的使用说明

    SQL中的left outer join,inner join,right outer join用法详解 使用关系代数合并数据 关系代数 合并数据集合的理论基础是关系代数,它是由E.F.Codd于19 ...

  2. 【Linux】关闭selinux

    vi /etc/selinux/config 将SELINUX=enforcing改为SELINUX=disabled 设置后需要重启才能生效

  3. LOJ 2719 「NOI2018」冒泡排序——模型转化

    题目:https://loj.ac/problem/2719 首先要发现合法的充要条件是 | LDS | <=2 ! 因为有没用的步数,说明一个元素先往左移.又往右移(不会先往右移再往左移,因为 ...

  4. node js 操作redis promise

    连接 redis = require('redis') var client = redis.createClient('6379', '127.0.0.1'); client.on('connect ...

  5. xml解析用正则解决没有标签的文本的解析不出异常

    如  <q>sasas<w>eqwe</w>ddas</q> package com.people.xmlToSql; import java.io.F ...

  6. 解决“/bin/bash^M: bad interpreter: No such file or directory”

    在执行shell脚本时提示这样的错误主要是由于shell脚本文件是dos格式,即每一行结尾以\r\n来标识,而unix格式的文件行尾则以\n来标识.  查看脚本文件是dos格式还是unix格式的几种办 ...

  7. javascript中call(),apply()用法

    ​ //上下文模式:根据用户传递的参数产生不同的结果 //实现方式:call/apply:这两个都是定义在Function.prototype.call——>目的:任何函数都可以访问到call/ ...

  8. Python异或加密字符串

    import os import sys import struct def enc(path, key): path_ret = "" for i in range(0, len ...

  9. vue2.0 项目小总结

    最近做了一个vue的PC端的项目,不大,真正用到vue的东西也不是太多,逻辑处理用到了不少原生js东西. 1.图片渲染 后台返回base64格式数据,一开始绑定src,提示pic字段未定义,懵逼了好久 ...

  10. VB - 错误处理

    1.最常见的错误是运行时错误,也就是说错误在脚本正在运行的时候发生,是脚本试图进行非法操作的结果.例如零被作为除数.在vbs中,任何运行时错误都是致命的,此时,脚本将停止运行,并在屏幕上显示一个错误消 ...