san - 主席樹優化建圖 - 強連通分量
阿新 • • 發佈:2018-12-09
題目大意:每一個人有三個屬性(ai,bi,ci),定義一個人比另一個大當且僅當有至少兩維更大。保證a,b,c分別是三個排列。執行以下程式碼:
//p is a permutation of [1,n]
int ans=p[1];
for(int i=2;i<=n;i++)
if(person[p[i]]>person[ans]) ans=p[i];
return ans;
問有多少人,使得存在至少一個排列,使得他是ans。
題解:
建圖,這是個競賽圖,縮點,這是條鏈,顯然不在鏈上第一坨點的人不會是答案,而由於強連通的競賽圖存在哈密頓迴路,因此在第一坨點上的人一定有可能成為答案,因此用主席樹優化建圖跑tarjan即可。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
const int N=100010;
struct A{
int a,b,c;A(int _a=0,int _b=0,int _c=0) { a=_a,b=_b,c=_c; }
inline int input() { return a=inn(),b=inn(),c=inn(); }
inline bool operator<(const A &n)const { return int(a>n.a)+int(b>n.b)+int(c>n.c)<=1; }
inline bool operator>(const A &n)const { return int(a>n.a)+int(b>n.b)+int(c>n.c)>=2; }
inline int show()const { return debug(a)sp,debug(b)sp,debug(c)ln,0; }
}a[N];
namespace subtask1{
const int N=20;int p[N],ans[N];
inline int brute_force_20(int n)
{
rep(i,1,n) p[i]=i,ans[i]=0;
do{
int t=p[1];
rep(i,2,n) if(a[p[i]]>a[t]) t=p[i];
ans[t]=1;
}while(next_permutation(p+1,p+n+1));
rep(i,1,n) printf("%d\n",ans[i]);return 0;
}
}
namespace subtask23{
const int N=2010,M=N*N/2;
struct edges{
int to,pre;
}e[M];int h[N],etop,vis[N],dfn[N],low[N],dfc,cc,bel[N],ind[N];stack<int> s;
inline int add_edge(int u,int v) { return e[++etop].to=v,e[etop].pre=h[u],h[u]=etop; }
int tarjan(int x)
{
vis[x]=1,dfn[x]=low[x]=++dfc,s.push(x);
for(int i=h[x],y;i;i=e[i].pre)
if(!vis[y=e[i].to]) tarjan(y),low[x]=min(low[x],low[y]);
else if(vis[y]==1) low[x]=min(low[x],dfn[y]);
if(low[x]==dfn[x])
{
bel[x]=++cc,vis[x]=2;
for(int y=s.top();y^x;y=s.top())
bel[y]=cc,vis[y]=2,s.pop();s.pop();
}
return 0;
}
inline int brute_force_60(int n)
{
memset(vis,0,sizeof(int)*(n+1));
memset(ind,0,sizeof(int)*(n+1));
rep(i,1,n) rep(j,i+1,n)
if(a[i]>a[j]) add_edge(i,j);
else add_edge(j,i);
dfc=0,cc=0;
rep(i,1,n) if(!vis[i]) tarjan(i);
rep(x,1,n) for(int i=h[x],y;i;i=e[i].pre)
if(bel[x]^bel[y=e[i].to]) ind[bel[y]]++;
rep(i,1,n) printf("%d\n",int(ind[bel[i]]==0));
return 0;
}
}
namespace subtask4{
const int NC=6100000,M=14000000,N=100010;
struct edges{
int to,pre;
}e[M];stack<int> s;
int h[NC],etop,vis[NC],dfn[NC],low[NC],dfc,cc,bel[NC],ind[NC],hs[NC],isr[NC];
inline int add_edge(int u,int v) { return e[++etop].to=v,e[etop].pre=h[u],h[u]=etop; }
int tarjan(int x)
{
vis[x]=1,dfn[x]=low[x]=++dfc,s.push(x);
for(int i=h[x],y;i;i=e[i].pre)
if(!vis[y=e[i].to]) tarjan(y),low[x]=min(low[x],low[y]);
else if(vis[y]==1) low[x]=min(low[x],dfn[y]);
if(low[x]==dfn[x])
{
bel[x]=++cc,vis[x]=2;
for(int y=s.top();y^x;y=s.top())
bel[y]=cc,vis[y]=2,s.pop(),hs[cc]|=isr[y];
s.pop(),hs[cc]|=isr[x];
}
return 0;
}
int lc[NC],rc[NC],node_cnt,v[N],x[N],y[N];
inline int new_node() { return node_cnt++,lc[node_cnt]=rc[node_cnt]=0,node_cnt; }
int build(int &x,int l,int r)
{
x=new_node();if(l==r) return 0;int mid=(l+r)>>1;
build(lc[x],l,mid),build(rc[x],mid+1,r);
return add_edge(x,lc[x]),add_edge(x,rc[x]);
}
inline int AddEdge(int x,int l,int r,int s,int t,int p)
{
if(s<=l&&r<=t) return add_edge(p,x);int mid=(l+r)>>1;
if(s<=mid) AddEdge(lc[x],l,mid,s,t,p);
if(mid<t) AddEdge(rc[x],mid+1,r,s,t,p);
return 0;
}
inline int update(int &x,int y,int l,int r,int p,int v)
{
x=new_node(),lc[x]=lc[y],rc[x]=rc[y];
if(l==r) return add_edge(x,v);int mid=(l+r)>>1;
if(p<=mid) update(lc[x],lc[y],l,mid,p,v);
if(mid<p) update(rc[x],rc[y],mid+1,r,p,v);
return add_edge(x,lc[x]),add_edge(x,rc[x]);
}
inline int prelude(int n)
{
int rt,tmp;build(rt,1,n);
rep(i,1,n) v[x[i]]=i;
rep(i,1,n)
AddEdge(rt,1,n,1,y[v[i]],v[i]),
update(tmp,rt,1,n,y[v[i]],v[i]),rt=tmp;
return 0;
}
queue<int> q;vector<int> g[NC];int fr[NC];
inline int toposort()
{
rep(i,1,cc) if(!ind[i]) q.push(i);
while(!q.empty())
{
int x=q.front();q.pop();
Rep(i,g[x])
{
int y=g[x][i];
ind[y]--,fr[y]|=fr[x]|hs[x];
if(!ind[y]) q.push(y);
}
}
return 0;
}
inline int acceptable_solution(int n)
{
node_cnt=n;rep(i,1,n) isr[i]=1;
rep(i,1,n) x[i]=a[i].a,y[i]=a[i].b;prelude(n);
rep(i,1,n) x[i]=a[i].a,y[i]=a[i].c;prelude(n);
rep(i,1,n) x[i]=a[i].b,y[i]=a[i].