BZOJ4684 : Company Organization

二分答案,转化为判定问题。

建立有向图,$a->b$连边表示$a$是$b$的子集,至此可以处理掉$1$和$2$。

对于$5$,则往对应点的集合塞一个元素,即可满足$5$。

首先求出强连通分量进行缩点,再递推出每个集合的必备元素以及每个集合的所有子集,用bitset加速,可以做到$O(\frac{m^2}{32})$。

然后对于$4$,首先检验一下$5$造成的必备元素是否有交,然后将所有既能到$x$又能到$y$的集合都标记为空集,这一步同样可以用bitset加速,做到$O(\frac{nm}{32})$。

知道哪些集合必须是空集之后,再检查是否存在一个集合,满足它必须是空集但是却又有操作$5$的元素。

最后再检查$3$即可,如果$x$和$y$所属同一个强连通分量或两个都是空集则矛盾。

时间复杂度$O(\frac{m^2\log m}{32})$。

#include<cstdio>
const int N=105,M=10005,E=M*2;
int n,m,U,i,j,x,y,e[M][3],l,r,mid,ans;
int g[3][N],v[3][E],nxt[3][E],ed;
int d[N],vis[N],h,t,q[N],f[N],empty[N];
struct BIT{
  unsigned int v[M>>5];
  BIT(){}
  void clear(){for(int i=0;i<=U;i++)v[i]=0;}
  void set(int x){v[x>>5]^=1U<<(x&31);}
  void operator|=(const BIT&b){for(int i=0;i<=U;i++)v[i]|=b.v[i];}
  bool operator&(const BIT&b){for(int i=0;i<=U;i++)if(v[i]&b.v[i])return 1;return 0;}
  void pick(const BIT&b,const BIT&w){
    for(int i=t=0;i<=U;i++){
      unsigned int x=v[i]&b.v[i]&w.v[i];
      while(x){
        q[++t]=i<<5|__builtin_ctz(x&-x);
        x-=x&-x;
      }
    }
  }
}s[N],sub[N],w;
inline void add(int x,int y){
  v[0][++ed]=y;nxt[0][ed]=g[0][x];g[0][x]=ed;
  v[1][ed]=x;nxt[1][ed]=g[1][y];g[1][y]=ed;
}
inline void ADD(int x,int y){d[y]++;v[2][++ed]=y;nxt[2][ed]=g[2][x];g[2][x]=ed;}
void dfs1(int x){
  vis[x]=1;
  for(int i=g[0][x];i;i=nxt[0][i])if(!vis[v[0][i]])dfs1(v[0][i]);
  q[++t]=x;
}
void dfs2(int x,int y){
  vis[x]=0,f[x]=y,s[y]|=s[x],sub[y]|=sub[x];
  for(int i=g[1][x];i;i=nxt[1][i])if(vis[v[1][i]])dfs2(v[1][i],y);
}
bool check(int mid){
  for(U=0,i=1;i<=mid;i++)if(e[i][0]==5)U++;
  if(U<n)U=n;
  U=(U-1)>>5;
  w.clear();
  for(ed=0,i=1;i<=n;i++){
    g[0][i]=g[1][i]=g[2][i]=d[i]=empty[i]=0;
    s[i].clear();
    sub[i].clear();
    sub[i].set(i-1);
    w.set(i-1);
  }
  for(t=0,i=1;i<=mid;i++){
    x=e[i][1],y=e[i][2];
    if(e[i][0]==1)add(x,y);
    if(e[i][0]==2)add(x,y),add(y,x);
    if(e[i][0]==5)s[x].set(t),s[y].set(t++);
  }
  for(t=0,i=1;i<=n;i++)if(!vis[i])dfs1(i);
  for(i=n;i;i--)if(vis[q[i]])dfs2(q[i],q[i]);
  for(ed=0,i=1;i<=n;i++)for(j=g[0][i];j;j=nxt[0][j])if(f[i]!=f[v[0][j]])ADD(f[i],f[v[0][j]]);
  for(t=0,h=i=1;i<=n;i++)if(f[i]==i&&!d[i])q[++t]=i;
  while(h<=t)for(i=g[2][x=q[h++]];i;i=nxt[2][i]){
    s[v[2][i]]|=s[x];
    sub[v[2][i]]|=sub[x];
    if(!(--d[v[2][i]]))q[++t]=v[2][i];
  }
  for(i=1;i<=mid;i++)if(e[i][0]==4){
    x=f[e[i][1]],y=f[e[i][2]];
    if(s[x]&s[y])return 0;
    for(sub[x].pick(sub[y],w);t;t--)empty[q[t]+1]=1,w.set(q[t]);
  }
  for(i=1;i<=n;i++)if(f[i]==i)if((s[i]&s[i])&&empty[i])return 0;
  for(i=1;i<=mid;i++)if(e[i][0]==3){
    x=f[e[i][1]],y=f[e[i][2]];
    if(x==y)return 0;
    if(empty[x]&&empty[y])return 0;
  }
  return 1;
}
int main(){
  while(1){
    scanf("%d%d",&n,&m);
    if(!n)return 0;
    for(i=1;i<=m;i++)scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
    l=1,r=m,ans=0;
    while(l<=r)if(check(mid=(l+r)>>1))l=(ans=mid)+1;else r=mid-1;
    printf("%d\n",ans);
  }
}

  

时间: 2024-10-11 06:37:03

BZOJ4684 : Company Organization的相关文章

DataComm Review NetworkLayer Part1

Network and transport layer Part1 Features of transport layer and network layer transport layer: end-to-end channel; reliable communication(segmenting + ARQ): addressing of individual applications(ports): network layer: addressing and routing of pack

iOS证书相关概念详解

关于开发证书配置(Certificates&Identifiers&Provisioning Profiles),相信做iOS开发的同学没少被折腾,本文将对相关概念做个系统的梳理. 在进行iOS证书申请之前,假设你使用过Apple设备且注册过Apple ID.首先,必须加入苹果开发者计划(Enrollin iOS Developer Program to become a member),分为Individual和Company/Organization两种类型. 下文主要基于个人开发者账

Android 系统调用 汇总

intent大全: 1.从google搜索内容 Intent intent = new Intent(); intent.setAction(Intent.ACTION_WEB_SEARCH); intent.putExtra(SearchManager.QUERY,"searchString") startActivity(intent); 2.浏览网页 Uri uri =Uri.parse("http://www.google.com"); Intent it 

iOS 6 Passbook 入门 1/2

Passbook 是苹果发布的 iOS 6 技术中最火热的一个, 它所带来的开创性超过我们的想象. Passbook 是一些是一个非常棒的组合. 四项独立的技术结合到一起,为 iPhone 用户带来了一个全新的体验: 新的 iOS 框架 PassKit 全新的 Passbook 应用,随着 iOS 一起绑定发布 苹果的 推送通知 服务(这次会保证发送成功) 你自己的服务端代码! Passbook 和你曾经用到过的其他苹果的技术很不同. 让他变得与众不同的是关于一个文件格式的概念. 由你来创建 P

iOS Provisioning Profile(Certificate)与Code Signing详解

摘自:http://blog.csdn.net/phunxm/article/details/42685597 引言 关于开发证书配置(Certificates & Identifiers & Provisioning Profiles),相信做 iOS 开发的同学没少被折腾.对于一个 iOS 开发小白.半吊子(比如像我自己)抑或老兵,或多或少会有或曾有过以下不详.疑问.疑惑甚至困惑: 什么是App ID?Explicit/Wildcard App ID有何区别?什么是App Group

苹果 App Store账号申请和证书申请发布app等知识

app store为开发者提供四种类型的申请: 个人ios开发者计划$99/年 公司ios开发者计划$99/年 企业ios开发者计划$299/年 高校ios开发者计划免费 在这里主要介绍一下公司ios开发者计划,只有利用个人和公司ios开发者计划证书开发的应用,才能上app store.企业开发者计划主要是为本公司开发软件,并安装到本公司的硬件设备上,不能上app store.下面主要介绍一下公司ios开发者计划的申请. 申请帐号: 打开连接:http://developer.apple.com

Apache+SVN+Review Board代码审核服务器搭建流程

一.简介 代码审查(CodeReview)不但可以提高质量,而且还是一个知识共享和指导的极好的手段.ReviewBoard是一款比较优秀的,开源的基于WEB的代码审查工具. 二.准备工作 2.1.安装依赖包 yum -y install gcc gcc-c++ make cmake autoconfautomake libffi libffi-devel ncurses* bison* zlib* expat* openssl* apr* neon* 2.2.安装Apache yum -y in

2016年最新苹果开发者账号注册申请流程最强详解!

准备工作:一张visa或者万事达国际信用卡(开通visa或master功能的信用卡).公司邮箱.公司网站(需与邮箱后缀一致).苹果企业开发者账号,分为两种.第一种Enterprise Program为公司内部员工打包测试用,不可公开下载:对外发布的是第二种,为Developer Program. 一.Enterprise Program(苹果公司售价$299,约合¥1988). 此账号的作用:企业账号是苹果给企业用户用来进行内部测试用的一种账号,我们可以通过该账号生成的证书打包APP,放于企业的

iOS—如何申请苹果公司开发者账号流程详细图文介绍(包括邓白氏编码的申请方法详细介绍)

写在开头~ 这是我第一次申请苹果的企业开发者账号,走了很多弯路,网上很多帖子写的不明不白,这次从申请到拿到结束大概花了1个月多点的时间,上个月就申请完了,一直在忙公司项目的事情,所以现在才有时间来写这篇博客,希望能帮助到大家 转载注明出处:http://www.cnblogs.com/northwan/p/4781127.html 正文: 我们要申请开发者账号,首先就需要先注册一个苹果的appleid,然后再这个账号的基础上去继续,这个相信大家都知道 这是申请appleid的地址: https: