QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#229437#7640. Colorful Cyclesucup-team088#WA 1339ms12028kbC++1711.8kb2023-10-28 16:10:142023-10-28 16:10:15

Judging History

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

  • [2024-07-04 22:58:32]
  • hack成功,自动添加数据
  • (/hack/728)
  • [2023-10-28 16:10:15]
  • 评测
  • 测评结果:WA
  • 用时:1339ms
  • 内存:12028kb
  • [2023-10-28 16:10:14]
  • 提交

answer

#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
#include<chrono>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
ll mod = 1;
//constexpr ll mod = 998244353;
//constexpr ll mod = 1000000007;
const int mod17 = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;

using ld = double;
typedef pair<ld, ld> LDP;
const ld eps = 1e-10;
const ld pi = acosl(-1.0);

template<typename T>
void chmin(T& a, T b) {
    a = min(a, b);
}
template<typename T>
void chmax(T& a, T b) {
    a = max(a, b);
}
template<typename T>
vector<T> vmerge(vector<T>& a, vector<T>& b) {
    vector<T> res;
    int ida = 0, idb = 0;
    while (ida < a.size() || idb < b.size()) {
        if (idb == b.size()) {
            res.push_back(a[ida]); ida++;
        }
        else if (ida == a.size()) {
            res.push_back(b[idb]); idb++;
        }
        else {
            if (a[ida] < b[idb]) {
                res.push_back(a[ida]); ida++;
            }
            else {
                res.push_back(b[idb]); idb++;
            }
        }
    }
    return res;
}
template<typename T>
void cinarray(vector<T>& v) {
    rep(i, v.size())cin >> v[i];
}
template<typename T>
void coutarray(vector<T>& v) {
    rep(i, v.size()) {
        if (i > 0)cout << " "; cout << v[i];
    }
    cout << "\n";
}
ll mod_pow(ll x, ll n, ll m = mod) {
    if (n < 0) {
        ll res = mod_pow(x, -n, m);
        return mod_pow(res, m - 2, m);
    }
    if (abs(x) >= m)x %= m;
    if (x < 0)x += m;
    //if (x == 0)return 0;
    ll res = 1;
    while (n) {
        if (n & 1)res = res * x % m;
        x = x * x % m; n >>= 1;
    }
    return res;
}
//mod should be <2^31
struct modint {
    int n;
    modint() :n(0) { ; }
    modint(ll m) {
        if (m < 0 || mod <= m) {
            m %= mod; if (m < 0)m += mod;
        }
        n = m;
    }
    operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
bool operator<(modint a, modint b) { return a.n < b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= (int)mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += (int)mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
    if (n == 0)return modint(1);
    modint res = (a * a) ^ (n / 2);
    if (n % 2)res = res * a;
    return res;
}

ll inv(ll a, ll p) {
    return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
    fact[0] = modint(1);
    for (int i = 0; i < max_n - 1; i++) {
        fact[i + 1] = fact[i] * modint(i + 1);
    }
    factinv[max_n - 1] = modint(1) / fact[max_n - 1];
    for (int i = max_n - 2; i >= 0; i--) {
        factinv[i] = factinv[i + 1] * modint(i + 1);
    }
}
modint comb(int a, int b) {
    if (a < 0 || b < 0 || a < b)return 0;
    return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
    if (a < 0 || b < 0 || a < b)return 0;
    return fact[a] * factinv[a - b];
}

ll gcd(ll a, ll b) {
    a = abs(a); b = abs(b);
    if (a < b)swap(a, b);
    while (b) {
        ll r = a % b; a = b; b = r;
    }
    return a;
}
template<typename T>
void addv(vector<T>& v, int loc, T val) {
    if (loc >= v.size())v.resize(loc + 1, 0);
    v[loc] += val;
}
/*const int mn = 2000005;
bool isp[mn];
vector<int> ps;
void init() {
    fill(isp + 2, isp + mn, true);
    for (int i = 2; i < mn; i++) {
        if (!isp[i])continue;
        ps.push_back(i);
        for (int j = 2 * i; j < mn; j += i) {
            isp[j] = false;
        }
    }
}*/

//[,val)
template<typename T>
auto prev_itr(set<T>& st, T val) {
    auto res = st.lower_bound(val);
    if (res == st.begin())return st.end();
    res--; return res;
}

//[val,)
template<typename T>
auto next_itr(set<T>& st, T val) {
    auto res = st.lower_bound(val);
    return res;
}
using mP = pair<modint, modint>;
mP operator+(mP a, mP b) {
    return { a.first + b.first,a.second + b.second };
}
mP operator+=(mP& a, mP b) {
    a = a + b; return a;
}
mP operator-(mP a, mP b) {
    return { a.first - b.first,a.second - b.second };
}
mP operator-=(mP& a, mP b) {
    a = a - b; return a;
}
LP operator+(LP a, LP b) {
    return { a.first + b.first,a.second + b.second };
}
LP operator+=(LP& a, LP b) {
    a = a + b; return a;
}
LP operator-(LP a, LP b) {
    return { a.first - b.first,a.second - b.second };
}
LP operator-=(LP& a, LP b) {
    a = a - b; return a;
}

mt19937 mt(time(0));

const string drul = "DRUL";
string senw = "SENW";
//DRUL,or SENW
//int dx[4] = { 1,0,-1,0 };
//int dy[4] = { 0,1,0,-1 };

//------------------------------------

struct LowLink {
private:
	vector<vector<int>> G;
	vector<int> used, ord, low;
	vector<int> art;

	//make graph with bridge
	vector<vector<int>> fG;
	vector<vector<int>> ori;
	vector<int> trans;
public:
	LowLink(int n) {
		G.resize(n);
		used.resize(n, 0);
		ord.resize(n, 0);
		low.resize(n, 0);
	}
	void add_edge(int a, int b) {
		if (a == b)return;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	int dfs(int id, int k, int par) {
		used[id] = true;
		ord[id] = k++;
		low[id] = ord[id];
		bool is_art = false;
		int cnt = 0;
		for (auto&& to : G[id]) {
			if (!used[to]) {
				++cnt;
				k = dfs(to, k, id);
				low[id] = min(low[id], low[to]);
				if (~par && low[to] >= ord[id])is_art = true;
			}
			else if (to != par) {
				low[id] = min(low[id], ord[to]);
			}
		}
		if (par == -1 && cnt > 1)is_art = true;
		if (is_art)art.push_back(id);
		return k;
	}
	void complete() {
		int k = 0;
		rep(i, G.size()) {
			if (!used[i]) {
				k = dfs(i, k, -1);
			}
		}

	}
	vector<int> arts() {
		return art;
	}
	vector<bool> isart;
	int dfs2(int id, int par, int nm, int& tmp) {
		trans[id] = nm;
		ori[nm].push_back(id);
		used[id] = true;
		int memo = nm;
		if (isart[id]) {
			if (par >= 0) {
				fG[id].push_back(nm);
				fG[nm].push_back(id);
				nm = tmp; tmp++;
				ori[nm].push_back(id);
			}
			for (int to : G[id])if (!used[to]) {
				if (low[to] < ord[id]) {
					dfs2(to, id, memo, tmp);
				}
				else {
					fG[id].push_back(nm);
					fG[nm].push_back(id);
					int memo2 = nm;
					nm = tmp; tmp++;
					ori[nm].push_back(id);
					dfs2(to, id, memo2, tmp);
				}
			}
		}
		else {
			for (int to : G[id])if (!used[to]) {
				dfs2(to, id, nm, tmp);
			}
		}
		return memo;
	}
	//root is n
	//number of vertice is less than N+2*M
	void makegraph_vertice(int sz) {
		int n = G.size();
		fG.resize(sz);
		ori.resize(sz);
		trans.resize(n);
		fill(all(used), false);
		isart.resize(n);
		for (int id : art)isart[id] = true;
		int tmp = n + 1;
		dfs2(0, -1, n, tmp);
		rep(i, n)if (isart[i])trans[i] = i;
	}
	vector<vector<int>> get_graph() {
		return fG;
	}
	vector<int> get_trans() {
		return trans;
	}
	void debug() {
		rep(i, ori.size()) {
			cout << "hai " << i << "\n";
			for (int id : ori[i])cout << id << " ";
			cout << "\n";
		}
		cout << "trans\n";
		rep(i, trans.size())cout << trans[i] << " ";
		cout << "\n";
	}
	vector<vector<int>> get_vs() {
		vector<vector<int>> res;
		rep(i, ori.size()) {
			if (ori[i].size() > 1) {
				res.push_back(ori[i]);
			}
		}
		return res;
	}
};

using ar = array<int, 5>;
struct ufundo {
private:
	vector<int> par, sz;
	vector<int> col;
	vector<ar> mem;
public:
	ufundo(int n) {
		par.resize(n, 0);
		sz.resize(n, 1);
		col.resize(n, 0);
		rep(i, n) {
			par[i] = i;
		}
	}
	int find(int x) {
		if (par[x] == x)return x;
		else return find(par[x]);
	}
	void unite(int x, int y,int c) {
		x = find(x), y = find(y);
		if (x == y) {
			mem.push_back({ x,y,0,col[x],col[y]});
			col[x] |= (1 << c);
			return;
		}
		if (sz[x] > sz[y])swap(x, y);
		mem.push_back({ x,y,1,col[x],col[y]});
		par[x] = y; sz[y] += sz[x];
		col[y] |= col[x];
		col[y] |= (1 << c);
	}
	bool same(int x, int y) {
		return find(x) == find(y);
	}
	int getsize(int k) {
		return sz[find(k)];
	}
	void undo(int num) {
		rep(_, num) {
			assert(mem.size());
			ar a = mem.back(); mem.pop_back();
			rep(i, 2)col[a[i]] = a[i + 3];
			if (!a[2])continue;
			int x = a[0], y = a[1];
			par[x] = x;
			sz[y] -= sz[x];
		}
	}
	int getcol(int x) {
		return col[find(x)];
	}
};



struct edge {
	int to, col;
};
void solve() {
	int n, m; cin >> n >> m;
	vector<vector<edge>> G(n);
	LowLink lt(n);
	rep(i, m) {
		int a, b, c; cin >> a >> b >> c; a--; b--; c--;
		G[a].push_back({ b,c });
		G[b].push_back({ a,c });
		lt.add_edge(a, b);
	}
	lt.complete(); lt.makegraph_vertice(n + 2 * m);
	vector<vector<int>> vs = lt.get_vs();
	vector<int> trans(n,-1);
	bool exi = false;
	for (auto &v : vs) {
		vector<vector<edge>> g(v.size());
		rep(i, v.size())trans[v[i]] = i;
		for (int id : v)for (edge e : G[id]) {
			if (trans[e.to] >= 0) {
				int le = trans[id];
				int ri = trans[e.to];
				g[le].push_back({ ri,e.col });
				g[ri].push_back({ le,e.col });
			}
		}
		int sz = 1; while (sz < v.size())sz *= 2;
		using data = array<int, 3>;
		vector<vector<data>> ads(2 * sz - 1);
		auto ad = [&](int l, int r,data d) {
			using sar = array<int, 3>;
			vector<sar> v;
			v.push_back({ 0,0,sz });
			while (v.size()) {
				auto s = v.back(); v.pop_back();
				if (s[2] <= l || r <= s[1])continue;
				if (l <= s[1] && s[2] <= r) {
					ads[s[0]].push_back(d);
				}
				else {
					v.push_back({ 2 * s[0] + 1,s[1],(s[1] + s[2]) / 2 });
					v.push_back({ 2 * s[0] + 2,(s[1] + s[2]) / 2,s[2] });
				}
			}
		};
		rep(i, v.size()) {
			for (edge e: g[i])if (i < e.to) {
				data d = { i,e.to,e.col };
				ad(0, i, d);
				ad(i + 1, e.to, d);
				ad(e.to + 1, v.size(), d);
				ad(e.to, e.to + 1, { i,i,e.col });
				ad(i, i + 1, { e.to,e.to,e.col });
			}
		}
		ufundo u(v.size());
		function<void(int)> dfs=[&](int k) {
			for (data d : ads[k]) {
				u.unite(d[0], d[1], d[2]);
			}
			if (k < sz-1) {
				dfs(2 * k + 1);
				dfs(2 * k + 2);
			}
			else {
				int id = k - (sz - 1);
				if (id < v.size()) {
					for (edge e : g[id]) {
						int c = u.getcol(e.to);
						if (c == 7) {
							exi = true;
						}
					}
				}
			}

			u.undo(ads[k].size());
		};

		dfs(0);
		rep(i, v.size())trans[v[i]] = -1;
	}
	if (exi) {
		cout << "Yes\n";
	}
	else {
		cout << "No\n";
	}
}



signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    //cout << fixed<<setprecision(10);
    //init_f();
    //init();
    //init2();
    //while(true)
    //expr();
    int t; cin >> t; rep(i, t)
    solve();
    return 0;
}


Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 5ms
memory: 11940kb

input:

2
3 3
1 2 3
2 3 1
1 3 2
5 6
1 2 1
2 3 1
1 3 2
3 4 3
3 5 3
4 5 3

output:

Yes
No

result:

ok 2 token(s): yes count is 1, no count is 1

Test #2:

score: -100
Wrong Answer
time: 1339ms
memory: 12028kb

input:

100000
7 10
7 2 2
6 4 2
6 1 2
7 1 3
3 4 1
6 7 1
2 6 3
3 1 2
5 3 1
2 1 1
7 10
5 7 3
7 1 1
4 6 3
6 3 1
3 4 3
4 2 2
3 2 3
1 3 3
3 7 1
1 4 2
7 10
5 6 3
3 5 2
7 2 3
7 3 3
1 2 2
4 3 2
7 4 2
6 1 2
2 6 1
7 5 2
7 10
7 1 3
7 5 3
6 4 1
7 6 1
1 4 1
3 4 2
2 7 2
1 3 1
3 5 3
5 1 3
7 10
6 7 2
3 4 3
1 4 2
5 3 2
7 4 ...

output:

Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
No
Yes
Yes
Yes
Yes
Yes
No
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
No
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
No
...

result:

wrong answer expected NO, found YES [490th token]