QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#509086#4885. Triangular Cactus PathsJuanJLWA 132ms118072kbC++144.4kb2024-08-08 09:49:402024-08-08 09:49:41

Judging History

你现在查看的是最新测评结果

  • [2024-08-08 09:49:41]
  • 评测
  • 测评结果:WA
  • 用时:132ms
  • 内存:118072kb
  • [2024-08-08 09:49:40]
  • 提交

answer

#include <bits/stdc++.h>

#define fst first 
#define snd second
#define pb push_back
#define forn(i,a,b) for(int i = a; i < b; i++)
#define ALL(x) x.begin(),x.end()
#define SZ(x) (int)x.size()
#define mset(a,v) memset((a),(v),sizeof(a))

typedef long long ll;
using namespace std;

const int MAXN = 400000+5;
const int MAXP = 25;
const int MOD = 998244353;

vector<ll> adj[MAXN]; // graph
vector<ll> nadj[MAXN]; // tree

bool ap[MAXN]; // articulation point
bool visited[MAXN];
ll low[MAXN]; // graph
ll level[MAXN]; // graph
ll nlevel[MAXN]; // tree
ll nparent[MAXN]; // tree
vector<vector<ll>> comp;
vector<ll> apvisited;
vector<pair<ll,ll>> bridges;
bool repre[MAXN];
vector<ll> tour;
pair<ll,ll> inTour[MAXN];
ll blift[MAXN][MAXP];

void dfs(ll nd, ll p , ll lvl){
	
	low[nd]=level[nd]=lvl;
	ll childs = 0;
	visited[nd]=true;
	for(auto i:adj[nd]) if(i!=p){
		if(visited[i]){
			low[nd]=min(low[nd],level[i]);
			continue;
		}
		childs++;
		dfs(i,nd,lvl+1);
		low[nd]=min(low[nd],low[i]);
		if(low[i]>=level[nd]){
			ap[nd]=true;
		}
		if(low[i]>level[nd]) bridges.pb({nd,i});
	}
	
	
	
	if(p==-1&&childs>1){
		ap[nd]=true;
	}else if(p==-1){
		ap[nd]=false;
	}
	
	if(SZ(adj[nd])==1) ap[nd]=1;
}

void setColor(ll nd, ll p){
	if(visited[nd]) return;
	comp[SZ(comp)-1].pb(nd);
	visited[nd]=true;
	if(ap[nd]){ apvisited.pb(nd); return;}
	for(auto &i:adj[nd]){
		setColor(i,nd);
	}
}

void eulerTour(ll nd, ll p, ll lvl){
	if(visited[nd]) return;
	visited[nd]=true;
	nparent[nd]=p;
	nlevel[nd]=lvl;
	inTour[nd].fst=SZ(tour);
	tour.pb(repre[nd]);
	for(auto i:nadj[nd]) if(i!=p){
		eulerTour(i,nd,lvl+1);
	}
	inTour[nd].snd=SZ(tour);
	tour.pb(-repre[nd]);
}

void preCalc(ll n){
	forn(i,0,n){
		blift[i][0]=nparent[i];
	}
	forn(j,1,MAXP){
		forn(i,0,n){
			if(blift[i][j-1]==-1) blift[i][j]=-1;
			else blift[i][j] = blift[blift[i][j-1]][j-1];
		}
	}
}

ll lca(ll a, ll b){
	ll A,B; A = a; B = b;
	if(nlevel[A]>nlevel[B]) A = b, B = a;
	
	for(int i = MAXP-1; i >= 0; i--){
		if(blift[B][i]!=-1&&nlevel[A]<=nlevel[blift[B][i]]){
			B = blift[B][i];
		}
	}
	
	for(int i = MAXP-1; i >= 0; i--){
		if(blift[A][i]!=blift[B][i]){
			A=blift[A][i];
			B=blift[B][i];
		}
	}
	
	if(A==B){
		return A;
	}else{
		return nparent[A];
	}
}

long long bin_pow(long long a, long long b, long long m) {
    a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a % m;
        a = a * a % m;
        b >>= 1;
    }
    return res;
}

int main(){
	ll n,m; cin>>n>>m;
	ll u,v;
	forn(i,0,m){
		cin>>u>>v; u--; v--;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	
	dfs(0,-1,0);
	
	mset(visited,0);
	
	forn(i,0,n) if(!ap[i]&&!visited[i]){
		comp.pb({});
		setColor(i,-1);
		while(!apvisited.empty()){ visited[apvisited.back()]=false; apvisited.pop_back();}
		
	}
	
	//forn(i,0,n) cout<<i<<" "<<ap[i]<<'\n';
	
	bool cact = false;
	ll indice = 0;
	for(auto i:comp){
		//cout<<indice<<": \n";
		for(auto j:i){
			//cout<<j<<" ";
			nadj[j].pb(n+indice);
			nadj[n+indice].pb(j);
			if(SZ(i)==3)repre[n+indice]=true;
		}// cout<<'\n';
		indice++;
	}
	//cout<<'\n';
	for(auto i:bridges){
		nadj[i.fst].pb(i.snd);
		nadj[i.snd].pb(i.fst);
	}
	
	/*forn(i,0,n+indice){
		cout<<"I: "<<i<<'\n';
		for(auto j:nadj[i]) cout<<j<<" "; cout<<'\n';
	}*/
	
	mset(visited,0);
	mset(blift,-1);
	
	eulerTour(0,-1,0);
	/*for(auto i:tour) cout<<i<<" "; cout<<'\n';
	forn(i,0,n+SZ(comp)) cout<<" I: "<<i<<" -> "<<inTour[i].fst<<" "<<inTour[i].snd<<'\n';*/
	
	preCalc(n+SZ(comp));
	
	forn(i,1,SZ(tour)) tour[i]+=tour[i-1];
	
	vector<long long> fact(MAXN*2);
	fact[0]=1;
	fact[1]=1;
	for(int i = 2; i < MAXN*2; i++){
		fact[i]=(fact[i-1]*i)%MOD;
	}
	
	ll q; cin>>q;
	ll k; 
	while(q--){
		cin>>u>>v>>k; u--; v--;
		int LCA = lca(u,v);
		int bicomp = tour[inTour[u].first]-(nparent[LCA]!=-1?tour[inTour[nparent[LCA]].first]:0);
		bicomp += tour[inTour[v].first]-tour[inTour[LCA].first];
		int edges = (nlevel[u]-nlevel[LCA])+(nlevel[v]-nlevel[LCA]);
		//cout<<bicomp<<" "<<edges<<" "<<LCA<<'\n';
		if(u==v){
			if(k==0) cout<<1<<'\n';
			else cout<<0<<'\n';
			continue;
		}
		
		int linf = k-(edges-bicomp);
		if(linf<0) cout<<0<<'\n';
		else if(bicomp<linf) cout<<0<<'\n';
		else cout<<(long long)(fact[bicomp] * bin_pow((fact[linf]*fact[max(bicomp-linf,0)])%MOD,MOD-2,MOD))%MOD<<'\n';
	}
	return 0;
}

详细

Test #1:

score: 100
Accepted
time: 8ms
memory: 118032kb

input:

8 10
1 2
2 3
3 1
3 4
4 5
5 6
6 4
4 7
7 8
8 4
6
1 1 0
1 1 1
1 4 3
6 2 4
5 7 4
3 4 2

output:

1
0
1
2
1
0

result:

ok 6 numbers

Test #2:

score: 0
Accepted
time: 7ms
memory: 118072kb

input:

2 1
1 2
8
1 1 0
1 1 1
1 2 0
1 2 1
2 1 0
2 1 1
2 2 0
2 2 1

output:

1
0
0
1
0
1
1
0

result:

ok 8 numbers

Test #3:

score: -100
Wrong Answer
time: 132ms
memory: 118044kb

input:

50 70
41 24
9 15
29 19
21 11
1 14
5 27
34 48
10 32
34 49
46 3
22 33
34 39
16 30
22 45
7 16
25 30
43 17
22 44
5 25
41 49
29 32
39 25
10 4
45 27
13 38
29 7
3 35
14 30
50 2
8 11
13 35
18 26
34 40
38 36
7 19
12 3
25 26
30 42
21 8
12 46
44 33
14 31
47 2
25 46
20 19
49 24
15 43
18 25
13 36
27 22
4 32
30 3...

output:

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
3
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
3
0
0
0
0
0
0
0
0
0
0
0
0
0
...

result:

wrong answer 17th numbers differ - expected: '0', found: '1'