1. 程式人生 > >san - 主席樹優化建圖 - 強連通分量

san - 主席樹優化建圖 - 強連通分量

題目大意:每一個人有三個屬性(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。
n

1 0 5 n\le10^5
題解:
建圖,這是個競賽圖,縮點,這是條鏈,顯然不在鏈上第一坨點的人不會是答案,而由於強連通的競賽圖存在哈密頓迴路,因此在第一坨點上的人一定有可能成為答案,因此用主席樹優化建圖跑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].