QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#130994 | #6396. Puzzle: Kusabi | segir187 | WA | 32ms | 10680kb | C++17 | 4.3kb | 2023-07-26 02:41:29 | 2023-07-26 02:41:31 |
Judging History
answer
#include <bits/stdc++.h> //Grzegorz Krawczyk
using namespace std;
typedef unsigned long long LL;
typedef long double LD;
#define rep(a,b) for(int a=0;a<int(b);a++)
#define rep2(a,b) for(int a=1;a<=(b);a++)
#define st first
#define nd second
#define pb push_back
#define mp make_pair
const int INF=INT_MAX/2;
const LL LINF=LLONG_MAX/2;
const int LIM=1e5+7;
/// cd /mnt/c/Users/OEM/staszic-zadanka/wwi2023/taj/prog
///flagi kompilacji:
///g++ -std=c++17 -static -Wall -pedantic -O3 -s -lm -o taj taj.cpp
struct pomocy
{
int i;
int lvl;
char typ;
};
vector<int> G[LIM]; /// krawedzi wychodzace z danego wierzcholka
char type[LIM]; /// typ danego wierzcholka: = musi miec kolege tego samego poziomu, < wiekszego, > mniejszego
vector<pair<int,int>> ans; /// tu trzymam pary wierzcholkow juz sparowanych
pomocy dp[LIM]; /// trzymam kogo "przekazuje" do ojca
bool valid=1; /// czy istnieje odpowiedz
int n;
void debugv(vector<pair<int,int>>& v,string s)
{
cerr<<s<<": ";
for(auto [a,b]:v) cerr<<"{"<<a<<","<<b<<"} ";
cerr<<"\n";
}
void calcdp(int ja,int oj,int cnt)
{
if(!valid) return;
/// kazdy vector trzyma nr i glebokosc syna o danym znaku
vector<pair<int,int>> eq,les,mor;
for(auto a:G[ja]) /// wrzucam swoich synow do wektorow
{
if(a==oj) continue;
calcdp(a,ja,cnt+1);
if(dp[a].typ=='=') eq.pb({dp[a].lvl,dp[a].i});
else if(dp[a].typ=='<') les.pb({dp[a].lvl,dp[a].i});
else if(dp[a].typ=='>') mor.pb({dp[a].lvl,dp[a].i});
}
/// ----- wrzucam siebie do wlasciwego wektora, potem wszystkie sortuje po glebokosciach -----
if(type[ja]=='=') eq.pb({cnt,ja});
else if(type[ja]=='<') les.pb({cnt,ja});
else if(type[ja]=='>') mor.pb({cnt,ja});
sort(eq.begin(),eq.end());
sort(les.begin(),les.end());
sort(mor.begin(),mor.end());
/// ----- sprawdzam czy sumarycznie musze wypchnac >1 wierzcholek do ojca -----
if(int(eq.size()%2)+abs(int(les.size())-int(mor.size()))>1)
{
valid=0;
//cerr<<ja<<" w1\n";
//debugv(eq,"eq");
//debugv(les,"les");
//debugv(mor,"mor");
return;
}
/// ----- sprawdzam czy musze wypchnac jakis wierzcholek do ojca bedac korzeniem -----
if(ja==1&&(int(eq.size()%2)+abs(int(les.size())-int(mor.size()))>0))
{
valid=0;
//cerr<<ja<<" w2\n";
return;
}
/// ----- rozpatruje synow z = -----
for(int i=0;i<int(eq.size())-1;i+=2)
{
if(eq[i].st==eq[i+1].st)
{
ans.pb({eq[i].nd,eq[i+1].nd});
continue;
}
if((eq.size()%2==0)||(i%2==1))
{
valid=0;
//cerr<<ja<<" w3\n";
return;
}
dp[ja]={eq[i].nd,eq[i].st,'='};
i--;
}
if((eq.size()%2==1)&&dp[ja].i==0) dp[ja]={eq.back().nd,eq.back().st,'='};
/// ----- rozpatruje synow gdy wiecej < -----
if(les.size()>mor.size())
{
for(int i=(int)les.size()-1,j=(int)mor.size()-1;i>=0&&j>=0;i--,j--)
{
if(les[i].st<mor[j].st)
{
ans.pb({les[i].nd,mor[j].nd});
continue;
}
if(i==j)
{
valid=0;
//cerr<<ja<<" w4\n";
return;
}
dp[ja]={les[i].nd,les[i].st,'<'};
j++;
}
if(dp[ja].i==0) dp[ja]={les[0].nd,les[0].st,'<'};
}
/// ----- rozpatruje synow gdy wiecej > lub po rowno <> -----
for(int i=0,j=0;i<int(les.size())&&j<int(mor.size());i++,j++)
{
if(les[i].st<mor[j].st)
{
ans.pb({les[i].nd,mor[j].nd});
continue;
}
if(les.size()==mor.size()||i!=j)
{
valid=0;
//cerr<<ja<<" w5\n";
return;
}
dp[ja]={mor[j].nd,mor[j].st,'>'};
i--;
}
if((les.size()<mor.size())&&dp[ja].i==0) dp[ja]={mor.back().nd,mor.back().st,'>'};
if(n==1e5&&ja==68071)
{
cout<<"68071: "<<type[68071]<<','<<ans.size()<<"\n";
cout<<eq.size()<<' '<<les.size()<<' '<<mor.size()<<'\n';
}
if(n==1e5&&dp[ja].i==68071)
{
cout<<ja<<": {"<<dp[ja].i<<','<<dp[ja].lvl<<','<<dp[ja].typ<<"}\n";
}
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0);
cin>>n;
rep(i,n-1)
{
int a,b;
string s;
cin>>a>>b>>s;
G[a].pb(b);
G[b].pb(a);
if(s=="Tong") type[a]='=';
else if(s=="Duan") type[a]='<';
else if(s=="Chang") type[a]='>';
}
calcdp(1,1,1);
if(!valid)
{
cout<<"NO\n";
//for(auto [a,b]:ans) cerr<<a<<' '<<b<<'\n';
return 0;
}
if(n==1e5)
{
rep(i,ans.size())
{
int a=ans[i].st,b=ans[i].nd;
if(a==68071||b==68071) cout<<i<<' '<<a<<' '<<b<<'\n';
}
}
cout<<"YES\n";
for(auto [a,b]:ans) cout<<a<<' '<<b<<'\n';
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 6628kb
input:
8 2 1 - 3 1 - 4 2 Tong 5 2 Tong 6 3 Duan 7 3 - 8 7 Chang
output:
YES 4 5 6 8
result:
ok Correct.
Test #2:
score: 0
Accepted
time: 0ms
memory: 5860kb
input:
10 2 1 Duan 3 2 Duan 4 2 - 5 4 Chang 6 2 Chang 7 1 Duan 8 6 Tong 9 6 Tong 10 3 Chang
output:
YES 3 10 8 9 2 6 7 5
result:
ok Correct.
Test #3:
score: 0
Accepted
time: 2ms
memory: 6032kb
input:
2 2 1 Tong
output:
NO
result:
ok Correct.
Test #4:
score: -100
Wrong Answer
time: 32ms
memory: 10680kb
input:
100000 2 1 Duan 3 1 Duan 4 3 - 5 4 Duan 6 3 - 7 4 Duan 8 4 - 9 8 - 10 7 Duan 11 9 - 12 7 Duan 13 7 Duan 14 8 Duan 15 13 - 16 10 Duan 17 11 Duan 18 12 - 19 1 Duan 20 5 Duan 21 4 Duan 22 14 Duan 23 16 - 24 22 Duan 25 16 Duan 26 13 - 27 13 - 28 17 - 29 5 Duan 30 22 - 31 23 - 32 9 Duan 33 5 - 34 30 Duan...
output:
68071: >,37 0 0 1 68071: {68071,8,>} 8419: {68071,8,>} 1145: {68071,8,>} 41 86193 68071 42 686 68071 YES 46666 56115 38802 88119 10006 93143 76473 31531 15988 42604 6569 30148 2008 11412 46703 64525 70618 71289 47748 81204 20514 42353 46131 97634 82155 83516 62410 66867 9975 15712 3205 4978 5622 830...
result:
wrong answer YES or NO expected in answer, but 68071: found.