QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#72983#4380. Travel planpoiAC ✓1376ms44100kbC++4.1kb2023-01-21 12:56:362023-01-21 12:56:38

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-01-21 12:56:38]
  • 评测
  • 测评结果:AC
  • 用时:1376ms
  • 内存:44100kb
  • [2023-01-21 12:56:36]
  • 提交

answer

#include "iostream"
#include "cstring"
#include "cstdio"
#include "algorithm"
#include "queue"
#include "vector"
#include "queue"
#include "stack"
#include "ctime"
#include "set"
#include "map"
using namespace std;
#define fi first
#define se second
#define vi vector<int>
#define pb push_back
#define eb emplace_back
#define pii pair<int,int>
#define mp make_pair
#define rep( i , a , b ) for( int i = (a) , i##end = b ; i <= i##end ; ++ i )
#define per( i , a , b ) for( int i = (a) , i##end = b ; i >= i##end ; -- i )
#define mem( a ) memset( a , 0 , sizeof (a) )
#define all( x ) x.begin() , x.end()
//#define int long long
typedef long long ll;
const int P = 998244353;
const int MAXN = 2e5 + 10;
int n , m , L;

namespace IO {
const int MAXSIZE = 1 << 20;
char buf[MAXSIZE], *p1, *p2;
#define gc()                                                               \
  (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin), p1 == p2) \
       ? EOF                                                               \
       : *p1++)
inline int rd() {
  int x = 0, f = 1;
  char c = gc();
  while (!isdigit(c)) {
    if (c == '-') f = -1;
    c = gc();
  }
  while (isdigit(c)) x = x * 10 + (c ^ 48), c = gc();
  return x * f;
}
char pbuf[1 << 20], *pp = pbuf;
inline void push(const char &c) {
  if (pp - pbuf == 1 << 20) fwrite(pbuf, 1, 1 << 20, stdout), pp = pbuf;
  *pp++ = c;
}
inline void write(int x) {
  static int sta[35];
  int top = 0;
  do {
    sta[top++] = x % 10, x /= 10;
  } while (x);
  while (top) push(sta[--top] + '0');
  push( 10 );
}
}

int pri[MAXN] , mu[MAXN] , en;
void sieve() {
	mu[1] = 1;
	for( int i = 2 ; i < MAXN ; ++ i ) {
		if( !pri[i] ) pri[++ en] = i , mu[i] = -1;
		for( int j = 1 ; j <= en && pri[j] * i < MAXN ; ++ j ) {
			pri[i * pri[j]] = 1;
			if( i % pri[j] == 0 ) {
				mu[i * pri[j]] = 0;
				break;
			}
			mu[i * pri[j]] = -mu[i];
		}
	}
}

vector<pii> ed[MAXN];

vi G[MAXN];

int cnt; vi g[MAXN];
int dfn[MAXN] , low[MAXN] , clo;
int stk[MAXN] , tp;

void tarjan( int u ) {
	dfn[u] = low[u] = ++ clo;
	stk[++ tp] = u;
	for( int v : G[u] ) {
		if( !dfn[v] ) {
			tarjan( v );
			low[u] = min( low[u] , low[v] );
			if( low[v] == dfn[u] ) {
				++ cnt;
				g[u].pb( cnt );
//					cout << "--->   " << u << ' ' << cnt << endl;
				int x;
				do {
					x = stk[tp];
					g[cnt].pb( x );
//					cout << "--->   " << cnt << ' ' << x << endl;
					-- tp;
				} while( x != v );
			}
		} else low[u] = min( low[u] , dfn[v] );
	}
}

int qm( int x ) {
	return ( x < P ? x : x - P );
}

int cnd[MAXN] , as;
void dfs( int u ) {
	int cn = ( u <= n ) , re = 0;
	for( int v : g[u] ) {
		dfs( v );
		re = ( re + cn * 1ll * cnd[v] ) % P;
		cn = qm( cn + cnd[v] );
	}
	if( u > n && g[u].size() > 1 ) as = qm( as + qm( re + re ) ) , cnd[u] = qm( cn + cn );
	else as = qm( as + re ) , cnd[u] = cn;
}

int re[MAXN] , res[MAXN];

void solve() {
	using namespace IO;
//	cin >> n >> m >> L;
	n = rd() , m = rd() , L = rd();
	rep( i , 1 , m ) {
		int u , v , w;
		u = rd() , v = rd() , w = rd();
//		scanf("%d%d%d",&u,&v,&w);
		ed[w].eb( u , v );
	}
	rep( k , 1 , L ) {
		vi nd;
		for( int t = k ; t <= L ; t += k ) 
			for( auto& e : ed[t] ) 
				G[e.fi].pb( e.se ) , G[e.se].pb( e.fi ) , nd.pb( e.fi ) , nd.pb( e.se );
		cnt = n , tp = 0 , clo = 0;
		vi rt;
		for( int x : nd ) if( !dfn[x] ) tarjan( x ) , rt.pb( x );
		as = 0;
		for( int x : rt ) {
			dfs( x );
		}
		re[k] = as;
		
		for( int x : nd ) G[x].clear() , dfn[x] = low[x] = 0 , g[x].clear() , cnd[x] = 0;
		rep( i , n + 1 , cnt ) g[i].clear() , dfn[i] = low[i] = 0 , cnd[i] = 0;
	}
	
	for( int k = 1 ; k <= L ; ++ k ) for( int t = 1 ; t * k <= L ; ++ t )
		res[k] = ( res[k] * 1ll + P + mu[t] * re[k * t] ) % P;
		
	int ans = 0;
	rep( i , 1 , L ) {
		ans ^= res[i];
//		printf("%d: %d %d\n",i,re[i],res[i]);
	}
	printf("%d\n",ans);
	
	rep( i , 1 , L ) ed[i].clear() , res[i] = re[i] = 0;
}

signed main() {
	sieve();
//	freopen("in","r",stdin);
//	freopen("out","w",stdout)
	int T;cin >> T;while( T-- ) solve();
//	solve();
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1376ms
memory: 44100kb

input:

405
3 3 6
1 2 6
2 3 4
3 1 5
5 4 10
1 2 10
1 3 1
2 4 8
4 5 9
100000 133392 100000
1 2 38759
1 3 63879
3 4 70473
1 5 79849
1 6 70562
5 7 83128
3 8 89713
4 9 6190
4 10 44171
7 11 99719
5 12 18707
1 13 33509
3 14 96110
11 15 84651
4 16 17844
3 17 64945
5 18 82684
9 19 94007
16 20 54506
11 21 10076
4 22 ...

output:

2
6
67078240
27003457
803251146
603512033
295921
64049237
209445
16863362
557344
176564099
933414
150267177
188786
226369182
148817
903133337
314734
69853467
162763
299319857
114659
836342484
146530
958360597
136066
983603446
157007
997887399
289109
178307076
262539
783549705
106788
19406148
73855
7...

result:

ok 405 lines