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);
}
}
BZOJ4684 : Company Organization的更多相关文章
- android Intent介绍
Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作.动作涉及数据.附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 ...
- 你想要了解但是却羞于发问的有关SSL的一切
Everything You Ever Wanted to Know About SSL (but Were Afraid to Ask) Or perhaps more accurately, &q ...
- iOS-开发者相关的几种证书
目录 引言 写在前面 一App IDbundle identifier 二设备Device 三开发证书Certificates 证书的概念 数字证书的概念 iOS开发证书 iOS开发证书的根证书 申请 ...
- Android系统调用
android 中intent是经常要用到的.不管是页面牵转,还是传递数据,或是调用外部程序,系统功能都要用到intent. 在做了一些intent的例子之后,整理了一下intent,希望对大家有用. ...
- android intent和intent action大全
1.Intent的用法:(1)用Action跳转1,使用Action跳转,如果有一个程序的AndroidManifest.xml中的某一个 Activity的IntentFilter段中 定义了包含了 ...
- iOS—如何申请苹果公司开发者账号流程详细图文介绍(包括邓白氏编码的申请方法详细介绍)
我们要申请开发者账号,首先就需要先注册一个苹果的apple id,然后再这个账号的基础上去继续,这个相信大家都知道 这是申请appleid的地址:https://appleid.apple.com/a ...
- [转载]iOS Provisioning Profile(Certificate)与Code Signing详解
原文:http://blog.csdn.net/phunxm/article/details/42685597 引言 关于开发证书配置(Certificates & Identifiers & ...
- 苹果IOS开发者账号的区别,企业账号,个人账号,公司团队账号,教育账号
苹果IOS开发者账号总结 详细地址:https://developer.apple.com/programs/which-program/ 个人账号(Individual): 费用99美金一年, 该账 ...
- 苹果IOS开发者账号总结--发布应用APP时team name是否可以随意写?
个人账号(Individual): 费用99美金一年, 该账号在App Store销售者只能显示个人的ID,比如zhitian zhang,单人使用.个人账号只能有一个开发者.100个苹果的iOS设备 ...
随机推荐
- 苹果应用 Windows 申请 普通证书 和Push 证书 Hbuilder 个推
最近使用Hbuilder 进行了HTML5开发,因为 HTML5 可以放在android 机器上,也可以放到 IOS机器上,所以很感兴趣,于是开发了一个小应用, 不过问题接着来了: 图1 如图所示:当 ...
- CLR via C#(08)-操作符
对于操作符,我们并不陌生,例如+,-,*,%等二元操作符,以及++,!等一元操作符.但是对于非基元类型,我们需要通过一些自定义方法才能使用这些操作符.今天主要和大家分享关于操作符重载和转换操作符的知识 ...
- 菜鸟学Linux命令:端口查看和操作命令
>>端口和进程 端口不是独立存在的,它是依附于进程的.某个进程开启,那么它对应的端口就开启了,进程关闭,则该端口也就关闭了.下次若某个进程再次开启,则相应的端口也再次开启. >> ...
- 菜鸟学Linux命令:nohup命令启动程序
在UNIX/LINUX中,普通进程用&符号放到后台运行,如果启动该程序的控制台logout,则该进程随即终止. 要实现守护进程,一种方法是按守护进程的规则去编程,比较麻烦:另一种方法是仍然用普 ...
- 【JAVA之泛型】
一.引例. 1.引例. 假设现在有一个ArrayList的容器,如果不使用泛型约束,则可以向容器中加入各种类型的对象,但是如果取出来的时候只是用一种类型的转换则肯定会抛出ClassCastExcept ...
- HDU 1227 Fast Food
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1227 题意:一维坐标上有n个点,位置已知,选出k(k <= n)个点,使得所有n个点与选定的点中 ...
- Solr入门之(3)常用概念说明(持续补充):
由于solr底层使用lucene,所以很多概念与lucene相同,下面是几个常用的概念: * Document:一个要进行索引的单元,相当于数据库的一行纪录,任何想要被索引的数据,都必须转化为Docu ...
- 数据结构之图 Part1
Part 1 预计使用7天的时间来过掉图相关的数据结构.第一天主要是一天图的基本概念,熟练掌握定义是一切交流和沟通的基础. 1定义 1.1图 有穷非空顶点,外加边. G(V,E) Graph Vert ...
- 源码方式安装mysql5.5
mysql5.5开始,源码配置编译工具configure变成了cmake,所以先要去把cmake装上.并安装make,bison,cmake,gcc-c++,ncurses的包 去http://www ...
- jQuery基础知识点(DOM操作)
1.样式属性操作 1)设置样式属性操作 ①设置单个样式: // 第一个参数表示:样式属性名称 // 第二个参数表示:样式属性值 $(selector).css(“color”, ...