主頁 >  其他 > 聯合省選 2021 A卷 題解

聯合省選 2021 A卷 題解

2021-04-23 12:40:20 其他

Day 1

卡牌游戲

這題是道簽到題,

容易想到把所有的 a , b a,b a,b 拿出來從小到大排序,然后列舉最小值,確定最大值,

先講一種很菜的 O ( n log ? 2 n ) O(n\log_2 n) O(nlog2?n) 做法,考慮 二分 最大值的位置,比這個最大值大的所有 a a a 顯然都要跳到它們對應的 b b b 處,可能還會出現不合法的情況,因此可以先用 后綴 維護出排序后下標在 [ i , 2 n ] [i,2n] [i,2n] 中的 a a a 對應的 b b b 的最大值,和 a a a 的個數,

其實還可以 O ( n ) O(n) O(n) 雙指標 ,因為最小值指標右移時,最大值指標不會左移,

如果忍受不了排序那個 O ( n log ? 2 n ) O(n\log_2 n) O(nlog2?n) ,可以 雙關鍵字桶排

矩陣游戲

考慮先不管上下限,求出一組解,然后再進行調整,

求這一組解很簡單,可以令第一行、第一列全部為 0 0 0 ,然后按順序求出其他值即可,

怎么調整?發現對于任意一個 2 × 2 2\times 2 2×2 的矩陣,我們把其中的兩個 ? 1 -1 ?1 ,另外兩個 + 1 +1 +1 ,它們的和不變,仍然滿足 b b b 的限制,如果只修改一行,可以把這一行上列編號為奇數的元素 + x +x +x ,列編號為偶數的元素 ? x -x ?x ,對于每一列也是同理,

但是為什么這樣調整可以達到合法的狀態?

發現根據 b b b 矩陣我們可以列出 ( n ? 1 ) ( m ? 1 ) (n-1)(m-1) (n?1)(m?1) 個方程,此時距離解出 a a a 的值還差 n + m ? 1 n+m-1 n+m?1 個方程,因此如果我們確定了第一行和第一列所有元素的值,矩陣中的其它 a a a 的值就是固定的了,而顯然我們可以通過操作讓第一行、第一列的每一個元素達到任意取值,

那么我們怎么調整?

設第 i i i 行調整的數為 c i c_i ci? ,第 i i i 列調整的數為 d i d_i di? ,那么
a i , j ′ = a i , j + ( ? 1 ) j + 1 c i + ( ? 1 ) i + 1 d j a'_{i,j}=a_{i,j} + (-1)^{j+1} c_{i} + (-1)^{i+1} d_{j} ai,j?=ai,j?+(?1)j+1ci?+(?1)i+1dj?
發現當 i , j i,j i,j 的奇偶性相同時, c i , d j c_i,d_j ci?,dj? 前面的系數相同,這時就是 和分約束 了,做不了,

因為我們只要讓相鄰的兩個數 c , d c,d c,d 的系數不同即可,因此可以
a i , j ′ = a i , j + ( ? 1 ) i + j ? 1 c i + ( ? 1 ) i + j d i a'_{i,j}=a_{i,j} +(-1)^{i+j-1}c_i + (-1)^{i+j}d_i ai,j?=ai,j?+(?1)i+j?1ci?+(?1)i+jdi?
然后就是 差分約束 啦,

由于 差分約束 中我們建出來的是一個 完全二分圖 ,因此用 B e l l m a n ? F o r d Bellman-Ford Bellman?Ford 也可以跑得很快,

圖函式

不難想到, f ( u , G ) f(u,G) f(u,G) 表示圖 G G G 中有多少個點 v v v 滿足同時存在 u → v u\to v uv v → u v\to u vu 且這兩條路徑上的點的編號都不小于 v v v

那么可以設 g i , j , k g_{i,j,k} gi,j,k? 表示當前的圖中是否存在路徑 i → j i\to j ij 滿足路徑上的點的編號都不小于 k k k

如果用 F l o y d Floyd Floyd 做,可以省掉 k k k 這一維,從大到小列舉中轉點 k k k 即可,

發現 G G G 很煩,想辦法怎么一次 F l o y d Floyd Floyd 做完,

刪邊有點難搞,可以考慮把邊按編號從大到小插入,發現我們的狀態 g g g 記錄一個 b o o l bool bool 值,比較浪費,于是設 h i , j h_{i,j} hi,j? 表示當前的圖中,所有 i → j i\to j ij 的路徑中 最大路徑上最小的邊的編號 (省略 k k k 這一維),

F l o y d Floyd Floyd 做,可以求出一個答案的 差分陣列 ,求一個 后綴和 就好了,

雖然時間復雜度是 O ( n 3 ) O\left(n^3\right) O(n3) ,但是這卻是這題最快的解法,

盡管如此,可能還要卡卡常,下面給出一個小優化:

F l o y d Floyd Floyd 時, i , j > k i,j>k i,j>k 的情況更新狀態 h i , j h_{i,j} hi,j? 沒有意義了,

證明:

因為 i , j i,j i,j 不會再當中轉點了,且這兩個點都不會作為 k k k 對答案造成貢獻了,所以更新狀態 h i , j h_{i,j} hi,j? 沒有意義,

寶石

D a y ?? 2 Day\; 2 Day2 簽到題,然而我不會,

先考慮一條鏈上怎么做,我們先跳到 S → T S\to T ST 中離 S S S 最近的顏色為 P 1 P_1 P1? 的點,然后跳離這個點最近的 P 2 P_2 P2? ,接著跳 P 3 P_3 P3? ……

那么現在要維護每個點后第一個顏色為 P 1 P_1 P1? 的點,以及這個點在寶石收集器中的下一種顏色對應的點,由于要跳很多步,用倍增優化跳的程序,

現在放到樹上,假設我們現在能 O ( 1 ) O(1) O(1) 求出任意一個點到根的路徑上離它最近的某種顏色的點,剩下的怎么做呢?老套路,把 S → T S\to T ST 的路徑分成 S → l c a , l c a → T S\to lca,lca\to T Slca,lcaT

先求在 S → l c a S\to lca Slca 上最多能收集多少個寶石,這不是直接倍增往上跳就行了嗎?

再求在 l c a → T lca\to T lcaT 上最多能收集多少個寶石,不好做,于是把路徑反過來,二分收集到的最后一顆寶石,預處理出每個點在寶石收集器中的上一種顏色對應的點,也是倍增優化,這樣就可以 O ( log ? 2 c log ? 2 n ) O(\log_2 c\log_2 n) O(log2?clog2?n) 地求了,

發現這時這兩部分可以分開求,

于是把詢問離線,遍歷這棵樹兩次,每次都動態維護當前點到根的路徑上離它最近的某種顏色的點,第一次遍歷時求出 S → l c a S\to lca Slca 這部分的答案,第二次遍歷時求出 l c a → T lca\to T lcaT 這部分的答案,這樣就可以了,

時間復雜度 O ( n log ? 2 n + q log ? 2 c log ? 2 n ) O(n\log_2 n+q\log_2 c\log_2 n) O(nlog2?n+qlog2?clog2?n)

P.S:這道題還可以用 點分治 做到 O ( n log ? 2 n + q log ? 2 n ) O(n\log_2 n+q\log_2 n) O(nlog2?n+qlog2?n)

滾榜

一眼看上去就是狀壓 D P DP DP

f s , i , j , k f_{s,i,j,k} fs,i,j,k? 表示狀態 s s s 中的隊伍還沒有公布,上一個公布的隊伍為 i i i b i = j b_i=j bi?=j ,剩余的 m m m 值為 k k k

空間復雜度 O ( 2 n m 2 n ) O\left(2^n m^2 n\right) O(2nm2n) ,時間復雜度 O ( 2 n ? 2 m 2 n 2 ) O\left(2^{n-2}m^2 n^2\right) O(2n?2m2n2) ,勉強能拿 40 40 40 分,還不如暴力 O ( n × n ! ) O(n\times n!) O(n×n!)

考慮消掉一維,去掉 j j j ,由于 b b b 按公布順序單調不下降,可以在每次加入一個隊伍 x x x 之后強制把沒有公布的隊伍的 b b b 都加上 max ? ( a i ? a x + [ x > i ] , 0 ) \max\left(a_i-a_x+[x>i],0\right) max(ai??ax?+[x>i],0) ,這樣就行了,

空間復雜度 O ( 2 n m n ) O\left(2^nmn \right) O(2nmn),時間復雜度 O ( 2 n ? 2 m n 2 ) O\left(2^{n-2}mn^2\right) O(2n?2mn2) (實際上時間肯定是跑不滿的),

支配

考場上覺得這題可做,就拼命弄這題,結果因為一些地方想錯了,最后只拿到樹的 15 15 15 分,

發現對于每個點 x x x ,圖中必定存在一條鏈,使得鏈上包含所有在 D x D_x Dx? 中的點,若構建一個新圖 G 1 G_1 G1? ,若原圖 G 0 G_0 G0? x x x D y D_y Dy? 中離 y y y 最近的點(即走最少的步數能到達 y y y 的點),就在 G 1 G_1 G1? 中加入一條邊 x → y x\to y xy ,發現 G 1 G_1 G1? 會變成一棵根節點是 1 1 1 的樹,事實上,這就是 支配樹

怎么建這棵樹?有 O ( m ) O(m) O(m) 的做法,但是因為這題允許我們 O ( n 2 ) O\left(n^2\right) O(n2) 建樹,就不如用好寫的 O ( n 2 ) O\left(n^2\right) O(n2) 做法了,

可以從 1 1 1 n n n 列舉一個點 i i i ,然后從 1 1 1 出發,不經過 i i i 遍歷整個圖,若最后點 j j j 沒有被遍歷到,那么 i ∈ D j i\in D_j iDj? ,顯然 i i i 的父親就是 D i D_i Di? ∣ D ∣ |D| D 最小的點,

接下來考慮怎么求答案,

顯然就是求加入 s → t s\to t st 后有多少個點的受支集合發生改變(顯然受支集合只會減小,即去除某些元素),假設某個點 i i i 在支配樹上的子樹中的所有點的 D D D 發生了改變(這顯然是因為 D i D_i Di? 中一些元素不在 D s D_s Ds? 中),可以發現 i i i 要滿足兩個條件:

  1. f a i fa_i fai? 不在支配樹中 1 → s 1\to s 1s 的路徑上,否則 D s ? D i D_s\subseteq D_i Ds??Di?
  2. 原圖中 t t t 不經過 f a i fa_i fai? 就可以到達 i i i ,否則新增的 1 → i 1\to i 1i 的路徑仍然必經 D i D_i Di? 中的每一個點,

可以把原圖中的邊反向,對于點 i i i ,求出有哪些點 j j j 不經過 f a j fa_j faj? 就能到達 i i i ,就可以求出所有滿足 條件2 的點了,

列舉這些點,篩選出其中滿足 條件1 的點即可,

但是這些點可能已經在支配樹上形成祖孫關系了,這個差分處理即可,

時間復雜度 O ( n 2 + n q ) O\left(n^2 +nq \right) O(n2+nq)


代碼

card

#include<cstdio>
#include<algorithm>
using namespace std;
#define fo(i,l,r) for(i=l;i<=r;++i)
#define M 2000005
#define N 1000005
const int inf=1000000001;
int m,s,a[N][2],minn[M],maxx[M],sum[M];bool state[M];
struct node{int num,id;bool type;}b[M];
bool cmp(node x,node y){return x.num<y.num;}
inline int mymin(int x,int y){return x<y?x:y;}
inline int mymax(int x,int y){return x>y?x:y;}
int main()
{
	freopen("card.in","r",stdin);
	freopen("card.out","w",stdout);
	register int i;
	int n,ans=inf,l,r,mid,L=1,res;
	scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&a[i][0]),b[++s]=(node){a[i][0],i,0};
	fo(i,1,n) scanf("%d",&a[i][1]),b[++s]=(node){a[i][1],i,1};
	sort(b+1,b+s+1,cmp);
	fo(i,1,s) a[b[i].id][b[i].type]=i;
	minn[s+1]=inf;
	for(i=s;i;--i)
	{
		if(b[i].type)
			minn[i]=minn[i+1],maxx[i]=maxx[i+1],sum[i]=sum[i+1];
		else
		{
			minn[i]=mymin(minn[i+1],a[b[i].id][1]);
			maxx[i]=mymax(maxx[i+1],a[b[i].id][1]);
			sum[i]=sum[i+1]+1;
		}
	}
	fo(i,1,s)
	{
		if(b[i].type&&!state[b[i].id]) --m,state[b[i].id]=1;
		if(m<0) goto end;
		l=L,r=s,res=-1;
		while(l<=r)
		{
			mid=l+r>>1;
			if(minn[mid+1]<i||maxx[mid+1]>mid||sum[mid+1]-(b[i].type&&a[b[i].id][0]>mid?1:0)>m) l=mid+1;
			else r=mid-1,res=mid;
		}
		if(res>0&&b[res].num-b[i].num<ans) ans=b[res].num-b[i].num;
		end:
		if(b[i].type)
		{
			if(a[b[i].id][0]<i) break;
			if(a[b[i].id][0]>L) L=a[b[i].id][0];
			++m,state[b[i].id]=0;
		}
		else
		{
			if(a[b[i].id][1]<i) break;
			if(a[b[i].id][1]>L) L=a[b[i].id][1];
			--m,state[b[i].id]=1;
		}
	}
	printf("%d\n",ans);
	return 0;
}

matrix

#include<cstdio>
using namespace std;
#define fo(i,l,r) for(i=l;i<=r;++i)
#define fd(i,r,l) for(i=r;i>=l;--i)
#define N 305
char p[15],buf[100005],*l=buf,*r=buf;
inline char gc()
{return l==r&&(r=(l=buf)+fread(buf,1,100005,stdin),l==r)?EOF:*l++;}
inline void read(int &k)
{
	char ch;while(ch=gc(),ch<'0'||ch>'9');k=ch-48;
	while(ch=gc(),ch>='0'&&ch<='9') k=k*10+ch-48;
}
inline void print(int x)
{
	if(!x) putchar('0');
	else
	{
		int len=0;
		while(x) p[++len]=x%10+48,x/=10;
		for(;len;--len) putchar(p[len]);
	}
	putchar(' ');
}
int a[N][N],b[N][N],wa[N][N],wb[N][N],fa[N],fb[N];
inline void mymin(int &x,int y){if(x>y) x=y;}
int main()
{
	freopen("matrix.in","r",stdin);
	freopen("matrix.out","w",stdout);
	register int i,j;
	int T,n,m,s,x,y;
	bool flag;
	read(T);
	while(T--)
	{
		read(n),read(m);
		for(i=1;i<n;++i)
			for(j=1;j<m;++j) read(b[i][j]);
		fo(i,1,n) a[i][1]=0;
		fo(i,1,m) a[1][i]=0;
		fo(i,2,n) fo(j,2,m) a[i][j]=b[i-1][j-1]-a[i][j-1]-a[i-1][j]-a[i-1][j-1];
		s=n+m;
		fo(i,1,n) fo(j,1,m) wa[i][j]=wb[j][i]=0x3f3f3f3f;
		fo(i,1,n) fa[i]=0;
		fo(i,1,m) fb[i]=0;
		fo(i,1,n) fo(j,1,m)
		{
			if(i+j&1) // d[j]-c[i]
			{
				mymin(wa[i][j],a[i][j]),
				mymin(wb[j][i],1000000-a[i][j]);
			}
			else // c[i]-d[j]
			{
				mymin(wb[j][i],a[i][j]),
				mymin(wa[i][j],1000000-a[i][j]);
			}
		}
		fo(x,1,s)
		{
			flag=1;
			fo(i,1,n) fo(j,1,m)
				if(fa[i]>fb[j]+wb[j][i])
					fa[i]=fb[j]+wb[j][i],flag=0;
			fo(i,1,m) fo(j,1,n)
				if(fb[i]>fa[j]+wa[j][i])
					fb[i]=fa[j]+wa[j][i],flag=0;
			if(flag) break;
		}
		if(x>s) goto out;
		fo(i,1,n) fo(j,1,m)
		{
			a[i][j]=i+j&1?a[i][j]+fa[i]-fb[j]:a[i][j]-fa[i]+fb[j];
			if(a[i][j]<0||a[i][j]>1000000) goto out;
		}
		puts("YES");
		fo(i,1,n)
		{
			fo(j,1,m) print(a[i][j]);
			putchar('\n');
		}
		continue;
		out:puts("NO");
	}
	return 0;
}

graph

#include<cstdio>
using namespace std;
#define M 200005
#define N 1005
char p[15],buf[100005],*pl=buf,*pr=buf;
inline char gc()
{return pl==pr&&(pr=(pl=buf)+fread(buf,1,100005,stdin),pl==pr)?EOF:*pl++;}
inline void read(int &k)
{
	char ch;while(ch=gc(),ch<'0'||ch>'9');k=ch-48;
	while(ch=gc(),ch>='0'&&ch<='9') k=k*10+ch-48;
}
inline void print(int x)
{
	if(!x) putchar('0');
	else
	{
		int len=0;
		while(x) p[++len]=x%10+48,x/=10;
		for(;len;--len) putchar(p[len]);
	}
	putchar(' ');
}
int f[N][N],ans[M];
inline int mymin(int x,int y){return x<y?x:y;}
inline void mymax(int &x,int y){if(x<y) x=y;}
int main()
{
	freopen("graph.in","r",stdin);
	freopen("graph.out","w",stdout);
	register int i,j,k,tmp;
	int x,y,n,m;
	read(n),read(m);
	for(i=1;i<=m;++i) read(x),read(y),f[x][y]=i;
	for(k=n;k;--k)
	{
		for(i=k+1;i<=n;++i) ++ans[mymin(f[i][k],f[k][i])];
		for(i=1;i<k;++i) if(f[i][k])
			for(j=1;j<=n;++j)
				mymax(f[i][j],mymin(f[i][k],f[k][j]));
		for(i=k+1;i<=n;++i) if(f[i][k])
			for(j=1;j<k;++j)
				mymax(f[i][j],mymin(f[i][k],f[k][j]));
		// i,j>k 因為 i,j 不會再當中轉點了,且這兩個點都不會作為 k 對答案造成貢獻了,所以沒有意義 
	}
	ans[m+1]=n;
	for(i=m;i;--i) ans[i]+=ans[i+1];
	for(i=1;i<=m+1;++i) print(ans[i]);
	return 0;
}

gem

#include<cstdio>
#include<vector>
using namespace std;
char p[15],buf[100005],*pl=buf,*pr=buf;
inline char gc()
{return pl==pr&&(pr=(pl=buf)+fread(buf,1,100005,stdin),pl==pr)?EOF:*pl++;}
inline void read(int &k)
{
	char ch;while(ch=gc(),ch<'0'||ch>'9');k=ch-48;
	while(ch=gc(),ch>='0'&&ch<='9') k=k*10+ch-48;
}
inline void print(int x)
{
	if(!x) putchar('0');
	else
	{
		int len=0;
		while(x) p[++len]=x%10+48,x/=10;
		for(;len;--len) putchar(p[len]);
	}
	putchar('\n');
}
#define fo(i,l,r) for(i=l;i<=r;++i)
#define M 400005
#define N 200005
#define C 50005
int fir[N],to[M],nex[M],w[N],num[C],id[C],las[C],f[N][18],g[N][18],h[N][18],dep[N],c,q,s,l,r,mid,now,res;
struct node{int st,ed,lca,mid,ans;}a[N];
vector<int>qry1[N],qry2[N];
inline void inc(int x,int y)
{
	to[++s]=y,nex[s]=fir[x],fir[x]=s;
	to[++s]=x,nex[s]=fir[y],fir[y]=s;
}
void dfs(int k)
{
	int i,tmp=las[w[k]];
	dep[k]=dep[f[k][0]]+1;
	g[k][0]=las[num[id[w[k]]+1]],
	h[k][0]=id[w[k]]?las[num[id[w[k]]-1]]:0;
	las[w[k]]=k;
	for(i=fir[k];i;i=nex[i])
		if(to[i]!=f[k][0])
			f[to[i]][0]=k,dfs(to[i]);
	las[w[k]]=tmp;
}
inline void swap(int &x,int &y){int z=x;x=y,y=z;}
inline int getlca(int u,int v)
{
	if(dep[u]<dep[v]) swap(u,v);
	for(int i=17;i>=0;--i)
		if(dep[f[u][i]]>=dep[v])
			u=f[u][i];
	if(u==v) return u;
	for(int i=17;i>=0;--i)
		if(f[u][i]!=f[v][i])
			u=f[u][i],v=f[v][i];
	return f[u][0];
}
void solveL(int k)
{
	int i,j,tmp;
	for(i=0;i<qry1[k].size();++i)
	{
		now=qry1[k][i],
		tmp=w[k]==num[1]?k:las[num[1]];
		for(j=17;j>=0;--j)
			if(dep[g[tmp][j]]>=dep[a[now].lca])
				tmp=g[tmp][j];
		a[now].mid=dep[tmp]>=dep[a[now].lca]?w[tmp]:0;
	}
	tmp=las[w[k]],las[w[k]]=k;
	for(i=fir[k];i;i=nex[i])
		if(to[i]!=f[k][0]) solveL(to[i]);
	las[w[k]]=tmp;
}
void solveR(int k)
{
	int i,j,tmp;
	for(i=0;i<qry2[k].size();++i)
	{
		now=qry2[k][i],l=id[a[now].mid]+1,r=c,res=l-1;
		while(l<=r)
		{
			mid=l+r>>1,
			tmp=w[k]==num[mid]?k:las[num[mid]];
			for(j=17;j>=0;--j)
				if(dep[h[tmp][j]]>=dep[a[now].lca])
					tmp=h[tmp][j];
			if(dep[tmp]>=dep[a[now].lca]&&id[w[tmp]]<=id[a[now].mid]+1) res=mid,l=mid+1;
			else r=mid-1;
		}
		a[now].ans=res;
	}
	tmp=las[w[k]],las[w[k]]=k;
	for(i=fir[k];i;i=nex[i])
		if(to[i]!=f[k][0]) solveR(to[i]);
	las[w[k]]=tmp;
}
int main()
{
	freopen("gem.in","r",stdin);
	freopen("gem.out","w",stdout);
	register int i;
	int j,n,m,x,y;
	read(n),read(m),read(c);
	fo(i,1,c) read(num[i]),id[num[i]]=i;
	fo(i,1,n) read(w[i]);
	for(i=1;i<n;++i) read(x),read(y),inc(x,y);
	dfs(1);
	fo(j,1,17) fo(i,1,n)
		f[i][j]=f[f[i][j-1]][j-1],
		g[i][j]=g[g[i][j-1]][j-1],
		h[i][j]=h[h[i][j-1]][j-1];
	read(q);
	fo(i,1,q)
		read(a[i].st),read(a[i].ed),
		a[i].lca=getlca(a[i].st,a[i].ed),
		qry1[a[i].st].push_back(i),
		qry2[a[i].ed].push_back(i);
	fo(i,1,m) las[i]=0;solveL(1);
	fo(i,1,m) las[i]=0;solveR(1);
	fo(i,1,q) print(a[i].ans);
	return 0;
}

ranklist

#include<cstdio>
using namespace std;
#define fo(i,l,r) for(i=l;i<=r;++i)
#define fd(i,r,l) for(i=r;i>=l;--i)
#define M 505
#define N 15
long long f[8195][N][M];
int a[N];
int main()
{
	freopen("ranklist.in","r",stdin);
	freopen("ranklist.out","w",stdout);
	register int k,j,i;
	int s,t,len,n,m,S,tmp,max=0;
	long long ans=0;
	scanf("%d%d",&n,&m),a[0]=-1;
	fo(i,1,n) scanf("%d",a+i);
	fo(i,1,n) if(a[i]>a[max]) max=i;
	S=(1<<n)-1;
	fo(i,1,n)
	{
		tmp=n*(a[max]-a[i]+(max<i));
		if(tmp<=m) f[S^1<<i-1][i][m-tmp]=1;
	}
	fd(s,S-1,1)
	{
		len=0;
		fo(i,1,n) if(s&1<<i-1) ++len;
		fo(i,1,n) if(!(s&1<<i-1))
			fo(k,1,n) if(s&1<<k-1)
			{
				tmp=(a[i]-a[k]+(i<k))*len;
				t=s^1<<k-1;
				if(tmp<0) tmp=0;
				fo(j,tmp,m) if(f[s][i][j])
					f[t][k][j-tmp]+=f[s][i][j];
			}
	}
	fo(i,1,n) fo(j,0,m) ans+=f[0][i][j];
	printf("%lld\n",ans);
	return 0;
}

dominator

#include<cstdio>
#include<algorithm>
using namespace std;
#define fo(i,l,r) for(i=l;i<=r;++i)
#define M 6005
#define N 3005
struct graph
{
	int fir[N],to[M],nex[M],s;
	inline void inc(int x,int y)
	{to[++s]=y,nex[s]=fir[x],fir[x]=s;}
}G,F,D_tree;
struct node
{
	int D[N],siz;
	inline void inc(int x){D[++siz]=x;}
}a[N],list[N];
int fa[N],vis[N],siz[N],dfn[N],sum[N],ord,time;
bool b[N],in[N];
void dfs1(int k)
{
	vis[k]=time;
	for(int i=G.fir[k];i;i=G.nex[i])
		if(b[G.to[i]]&&vis[G.to[i]]<time)
			dfs1(G.to[i]);
}
void dfs2(int k)
{
	vis[k]=time,list[k].inc(time);
	for(int i=F.fir[k];i;i=F.nex[i])
		if(b[F.to[i]]&&vis[F.to[i]]<time)
			dfs2(F.to[i]);
}
void dfs3(int k)
{
	siz[k]=1,dfn[k]=++ord;
	for(int i=D_tree.fir[k];i;i=D_tree.nex[i])
		dfs3(D_tree.to[i]),siz[k]+=siz[D_tree.to[i]];
}
int main()
{
	freopen("dominator.in","r",stdin);
	freopen("dominator.out","w",stdout);
	register int i,j;
	int n,m,q,x,y,ans,k;
	scanf("%d%d%d",&n,&m,&q);
	fo(i,1,m)
		scanf("%d%d",&x,&y),
		G.inc(x,y),F.inc(y,x);
	fo(i,1,n) b[i]=1;
	fo(i,2,n)
	{
		a[i].inc(1);
		time=i,b[i]=0,
		dfs1(1),vis[i]=i;
		fo(j,2,n) if(vis[j]<i)
			a[j].inc(i);
		b[i]=1;
	}
	fo(i,2,n)
	{
		fa[i]=a[i].D[1];
		fo(j,2,a[i].siz)
			if(a[a[i].D[j]].siz>a[fa[i]].siz)
				fa[i]=a[i].D[j];
	}
	fo(i,2,n) D_tree.inc(fa[i],i);
	dfs3(1);
	fo(i,1,n) vis[i]=0;
	fo(i,2,n)
	{
		time=i,b[fa[i]]=0;
		dfs2(i),b[fa[i]]=1;
	}
	b[0]=1;
	while(q--)
	{
		scanf("%d%d",&x,&y),ans=0;
		fo(i,1,n) sum[i]=0;
		i=x,b[1]=0;while(i>1) b[i]=0,i=fa[i];
		fo(j,1,list[y].siz)
		{
			k=list[y].D[j];
			if(b[fa[k]]) ++sum[dfn[k]],--sum[dfn[k]+siz[k]];
		}
		fo(j,1,n)
		{
			sum[j]+=sum[j-1];
			if(sum[j]) ++ans;
		}
		printf("%d\n",ans);
		i=x,b[1]=1;while(i>1) b[i]=1,i=fa[i];
	}
	return 0;
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/279335.html

標籤:其他

上一篇:性能優化篇之腳本策略

下一篇:Acwing.379 捉迷藏(最小路徑重復點覆寫)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more