您的位置:首页 > 其它

【NOIP2017提高A组模拟8.22】世界线

2017-08-23 10:59 351 查看
bitset模板

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<bitset>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;

const int maxn=2e5+5;

int fi[maxn],ne[maxn],qc[maxn],dui[maxn],ru[maxn],go[3][maxn],ru1[maxn];
int i,j,k,l,n,x,y,z,now,m,ss,now1,pc,ll,rr;
int ans;
bitset <30005> p[60005];
void add(int x,int y){
if (fi[x]==0) fi[x]=++now; else ne[qc[x]]=++now;
qc[x]=now; dui[now]=y;
}
void geans(int x){
int i=fi[x];
while (i){
y=dui[i];
p[y]=p[y] | p[x];
ru[y]--;
if (ru[y]==0){
go[z^1][++now1]=y;
ss--;
ans+=p[y].count();
}
i=ne[i];
}
}
void work1(){
now=0; ss=n;
fo(i,1,n) ru[i]=ru1[i];
fo(i,1,n) if(ru[i]==0){
go[0][++now]=i; ss--;
if (i>=ll && i<=rr) ans++;
}
z=0;
while (ss){
now1=0;
fo(i,1,now) geans(go[z][i]);
z^=1; now=now1;
}
}
void ge(){
fo(i,1,n) p[i].reset();
fo(i,ll,min(n,rr)) p[i].set(i-ll);
work1();
}
int main(){
//  freopen("t1.in","r",stdin);
freopen("worldline.in","r",stdin);
freopen("worldline.out","w",stdout);
scanf("%d%d",&n,&m);
fo(i,1,m){
scanf("%d%d",&x,&y);
add(x,y); ru[y]++;
}
fo(i,1,n) ru1[i]=ru[i];
ll=1; rr=30000;
while (ll<=n){
ge();
ll+=30000; rr+=30000;
}
ans=ans-m-n;
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: