用map建边。几乎1 A。
说明细节想清楚在复杂的题也是不难写的。一定要在写之前想清楚,不要想着写完再想
#include<bits/stdc++.h>
using namespace std;
#define maxn 1020
#define N 100020
#define rep(i,l,r) for(register int i = l ; i <= r ; i++)
#define repd(i,r,l) for(register int i = r ; i >= l ; i--)
#define rvc(i,S) for(register int i = 0 ; i < (int)S.size() ; i++)
#define rvcd(i,S) for(register int i = ((int)S.size()) - 1 ; i >= 0 ; i--)
#define fore(i,x)for (register int i = head[x] ; i ; i = e[i].next)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define prev prev_
#define stack stack_
#define inf 0x3f3f3f3f
typedef long long ll;
struct node{
int tp,x,y,c;
}dt[maxn];
struct node2{
int next,to;
}e[N * 10];
int head[N],cnt,sol[N],bcnt,low[N],dfn[N],belong[N],ins[N];
int s[N],tops,dfstime;
map <int,int> num,tag;
map <int,int>::iterator it;
map <int,int> mx[maxn];
map <pair<int,int>,int> rec[maxn];
vector <pair<int,int> > vec[N];
vector <int> c[N];
int tot,tot2;
int n,m,T;
int prime[N],tag2[N],cnt2;
void clear(){
rep(i,1,n){
mx[i].clear() , rec[i].clear();
}
rep(i,1,tot2 * 2) c[i].clear() , dfn[i] = head[i] = 0;
tops = dfstime = bcnt = cnt = tot2 = 0;
}
void pre(){
rep(i,2,100000){
if ( !tag2[i] ) prime[++cnt2] = i;
for (register int j = 1 ; j <= cnt2 && prime[j] * i <= 100000 ; j++){
tag2[i * prime[j]] = 1;
if ( i % prime[j] == 0 ) break;
}
}
}
void factor(int x){
if ( num[x] ) return;
num[x] = ++tot;
rep(i,1,x){
if ( prime[i] * prime[i] > x ) break;
if ( x % prime[i] == 0 ){
int c = 0;
while ( x % prime[i] == 0 ) c++ , x /= prime[i];
vec[tot].pb(mp(prime[i],c));
}
}
if ( x > 1 ) vec[tot].pb(mp(x,1));
}
inline void adde(int x,int y){
e[++cnt].to = y;
e[cnt].next = head[x];
head[x] = cnt;
}
void force_not(int x){
for (it = mx[x].begin() ; it != mx[x].end() ; ++it){
pair <int,int> cur = *it;
cur.se = 1;
if ( !tag[cur.fi] ){
adde(rec[x][cur] + tot2,rec[x][cur]); // force not choose
}
}
}
void force_not(int x,int y){
for (it = mx[x].begin() ; it != mx[x].end() ; ++it){
pair <int,int> cur = *it;
cur.se = 1;
if ( tag[cur.fi] || !rec[y][cur] ) continue;
adde(rec[x][cur] + tot2,rec[y][cur]); // if x , force not choose y
}
}
void init(){
rep(i,1,n){
// cout<<i<<endl;
for (it = mx[i].begin() ; it != mx[i].end() ; ++it){
pair <int,int> cur = *it;
// cout<<cur.fi<<" "<<cur.se<<endl;
while ( cur.se ){
rec[i][cur] = ++tot2;
cur.se--;
}
}
}
//tot2 + i : 1 ( 选了 )
//i : 0 ( 不选 )
rep(i,1,n){
for (it = mx[i].begin() ; it != mx[i].end() ; ++it){
pair <int,int> cur,cur2 = *it; cur = cur2;
cur.se--;
while ( cur.se ){
adde(rec[i][cur2] + tot2,rec[i][cur] + tot2);
adde(rec[i][cur],rec[i][cur2]);
cur.se-- , cur2.se--;
}
}
}
rep(i,1,m){
int tp = dt[i].tp , x = dt[i].x , y = dt[i].y , c = dt[i].c;
pair<int,int> cur; tag.clear();
if ( tp == 1 ){ //LCM
rvc(j,vec[c]){
cur = vec[c][j];
adde(rec[x][cur],rec[y][cur] + tot2);
adde(rec[y][cur],rec[x][cur] + tot2);
tag[cur.fi] = 1 , cur.se++;
adde(rec[x][cur] + tot2,rec[x][cur]);
adde(rec[y][cur] + tot2,rec[y][cur]);
}
force_not(x);
force_not(y);
}
else{ //GCD
rvc(j,vec[c]){
cur = vec[c][j] , tag[cur.fi] = 1;
adde(rec[x][cur],rec[x][cur] + tot2);
adde(rec[y][cur],rec[y][cur] + tot2);
cur.se++;
adde(rec[x][cur] + tot2,rec[y][cur]);
adde(rec[y][cur] + tot2,rec[x][cur]);
}
force_not(x,y);
force_not(y,x);
}
}
}
void dfs(int x){
low[x] = dfn[x] = ++dfstime;
s[++tops] = x , ins[x] = 1;
fore(i,x){
if ( !dfn[e[i].to] ) dfs(e[i].to) , low[x] = min(low[x],low[e[i].to]);
else if ( ins[e[i].to] ) low[x] = min(low[x],low[e[i].to]);
}
if ( dfn[x] == low[x] ){
int cur = s[tops--]; ++bcnt;
while ( cur != x ){
ins[cur] = 0 , belong[cur] = bcnt;
c[bcnt].pb(cur);
cur = s[tops--];
}
ins[cur] = 0 , belong[cur] = bcnt;
c[bcnt].pb(cur);
}
}
inline int get_v(int n,int x){
int r = x > n ? x - n : x;
if ( sol[r] == -1 ) return -1;
return x > n ? !sol[r] : sol[r];
}
bool two_SAT(int n){
rep(i,1,n) sol[i] = -1;
rep(i,1,n * 2) if ( !dfn[i] ) dfs(i);
rep(i,1,n){
if ( belong[i] == belong[i + n] ) return 0;
}
/* rep(i,1,bcnt){
int val = 1;
rvc(j,c[i]){
int cur = c[i][j];
if ( get_v(n,cur) == 0 ) val = 0;
fore(k,cur){
if ( get_v(n,e[k].to) == 0 ) val = 0;
}
if ( !val ) break;
}
rvc(j,c[i]){
if ( c[i][j] > n ) sol[c[i][j] - n] = !val;
else sol[c[i][j]] = val;
}
}*/
return 1;
}
int main(){
freopen("input.txt","r",stdin);
pre();
scanf("%d",&T);
rep(t,1,T){
clear();
scanf("%d %d",&n,&m);
rep(i,1,m){
char s[10]; int x,y,c,cur;
scanf("%s %d %d %d",s,&x,&y,&c) , x++ , y++;
factor(c) , cur = num[c];
rvc(j,vec[cur]){
mx[x][vec[cur][j].fi] = max(mx[x][vec[cur][j].fi],vec[cur][j].se);
mx[y][vec[cur][j].fi] = max(mx[y][vec[cur][j].fi],vec[cur][j].se);
}
if ( s[0] == 'L' ){
dt[i] = (node){1,x,y,cur};
}
else{
dt[i] = (node){2,x,y,cur};
}
}
init();
if ( two_SAT(tot2) ) cout<<"Solution exists\n";
else cout<<"Solution does not exist\n";
}
}