답안 #1023319

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1023319 2024-07-14T15:39:05 Z DobromirAngelov Spring cleaning (CEOI20_cleaning) C++14
37 / 100
100 ms 57556 KB
#include<bits/stdc++.h>
#define endl '\n'
#define int long long

using namespace std;

const int MAXN=1e5+5;
const int MAXQ=1e5+5;
const int MAXLOG=21;

int n,q;
vector<int> adj[MAXN];

bool leaf[MAXN];
int root=1;
int subLf[MAXN];
int depth[MAXN];
int cnt1[MAXN], cnt2[MAXN];
int ansOrg=0;

int tin[MAXN];
int order[2*MAXN];
int timer=0;

int lg2[2*MAXN];
int spT[2*MAXN][MAXLOG];

unordered_set<int> s;
int newCnt[MAXN];
vector<int> virtNodes;
vector<int> vAdj[MAXN];
int used[MAXN];

void dfs(int v,int par,int d)
{
    depth[v]=d;
    subLf[v]=0;
    if(leaf[v]) subLf[v]=1;

    for(auto u: adj[v])
    {
        if(u==par) continue;
        dfs(u,v,d+1);
        subLf[v]+=subLf[u];
    }
}

void dfs2(int v,int par)
{
    if(subLf[v]%2==1) cnt1[v]++;
    else cnt2[v]++;

    for(auto u: adj[v])
    {
        if(u==par) continue;
        cnt1[u]=cnt1[v];
        cnt2[u]=cnt2[v];
        dfs2(u,v);
    }
}

void dfs3(int v,int par)
{
    order[++timer]=v;
    tin[v]=timer;
    for(auto u: adj[v])
    {
        if(u==par) continue;
        dfs3(u,v);
        order[++timer]=v;
    }
}

void sparseTable()
{
    lg2[0]=-1; ///
    for(int i=1;i<=timer;i++)
    {
        lg2[i]=lg2[i/2]+1;
        spT[i][0]=order[i];
    }

    for(int j=1;(1<<j)<=timer;j++)
    {
        for(int i=1;i<=timer;i++)
        {
            if(i+(1<<(j-1))>timer) break;
            spT[i][j]=spT[i][j-1];
            if(depth[spT[i+(1<<(j-1))][j-1]]<depth[spT[i][j-1]]) spT[i][j]=spT[i+(1<<(j-1))][j-1];
        }
    }
}

int lca(int u,int v)
{
    if(tin[u]>tin[v]) swap(u,v);
    int d=tin[v]-tin[u]+1;
    int c1=spT[tin[u]][lg2[d]];
    int c2=spT[tin[v]-(1<<lg2[d])+1][lg2[d]];
    if(depth[c1]<=depth[c2]) return c1;
    return c2;
}

bool cmp(int u,int v)
{
    return tin[u]<tin[v];
}

int buildVirtTree()
{
    for(auto v: virtNodes) used[v]=1;

    sort(virtNodes.begin(), virtNodes.end(), cmp);
    int sz=virtNodes.size();
    for(int i=1;i<sz;i++)
    {
        virtNodes.push_back(lca(virtNodes[i-1], virtNodes[i]));
    }

    sort(virtNodes.begin(), virtNodes.end(), cmp);
    //for(auto v: virtNodes) cout<<v<<" "; cout<<endl;

    vector<int> nodes;
    for(auto v: virtNodes)
    {
        if(!nodes.empty() && nodes.back()!=v) nodes.push_back(v);
        if(nodes.empty()) nodes.push_back(v);
    }

    for(auto v: nodes) vAdj[v].clear();

    vector<int> st;
    for(auto v: nodes)
    {
        while(!st.empty() && lca(st.back(), v)!=st.back()) st.pop_back();
        if(!st.empty())
        {
            vAdj[st.back()].push_back(v);
        }
        st.push_back(v);
    }
//cout<<st[0]<<endl;

    //for(auto v: nodes) cout<<v<<" "; cout<<endl;

    return st[0];
}

pair<int,int> dfs_virt(int v,int par)
{//cout<<v<<endl;
    int ret=0;
    int cntUsed=0;
    if(used[v]) cntUsed=1;
    for(auto u: vAdj[v])
    {
        //if(u==par) continue;
        auto cur=dfs_virt(u,v);
        ret+=cur.first;
        cntUsed+=cur.second;
    }

    if(cntUsed%2==1 && par!=-1)
    {
        int cntOdd=cnt1[v]-cnt1[par];
        int cntEv=cnt2[v]-cnt2[par];
        ret+=cntOdd-cntEv;
    }

    return {ret, cntUsed};
}

signed main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

cin>>n>>q;
for(int i=1;i<n;i++)
{
    int u,v;
    cin>>u>>v;
    adj[u].push_back(v);
    adj[v].push_back(u);
}

for(int i=1;i<=n;i++)
{
    if(adj[i].size()==1) leaf[i]=1;
    else root=i;
}

dfs(root,-1,1);

dfs2(root,-1);

dfs3(root,-1);
sparseTable();

for(int i=1;i<=n;i++)
{
    if(i==root) continue;
    if(subLf[i]%2==1) ansOrg+=1;
    else ansOrg+=2;
}

for(int tt=0;tt<q;tt++)
{
    int d;
    cin>>d;
    for(int i=0;i<d;i++)
    {
        int v;
        cin>>v;
        newCnt[v]++;
        s.insert(v);
    }

    int ans=ansOrg+d;

    for(auto v: s)
    {
        if(leaf[v]) newCnt[v]--;
        newCnt[v]%=2;
        if(newCnt[v]>0) virtNodes.push_back(v);
    }

    if((subLf[root]+virtNodes.size())%2==1) cout<<-1<<endl;
    else
    {
        if(virtNodes.size()>0)
        {
            int virtRoot=buildVirtTree();
            ans+=dfs_virt(virtRoot,-1).first;
        }
        cout<<ans<<endl;
        for(auto v: virtNodes) used[v]=0;
    }

    for(auto v: s) newCnt[v]=0;
    s.clear();
    virtNodes.clear();
}

return 0;
}
/*
7 3
1 2
2 4
4 5
5 6
5 7
3 4
1 4
2 2 4
1 1
*/
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 7256 KB Output is correct
2 Incorrect 34 ms 15196 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 8024 KB Output is correct
2 Correct 6 ms 8028 KB Output is correct
3 Correct 46 ms 50376 KB Output is correct
4 Correct 48 ms 40900 KB Output is correct
5 Correct 64 ms 54212 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 11 ms 9564 KB Output is correct
2 Correct 8 ms 9308 KB Output is correct
3 Correct 64 ms 57292 KB Output is correct
4 Correct 100 ms 57556 KB Output is correct
5 Correct 62 ms 52048 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 26 ms 16728 KB Output is correct
2 Incorrect 18 ms 16220 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 46 ms 35588 KB Output is correct
2 Correct 66 ms 36180 KB Output is correct
3 Correct 45 ms 22100 KB Output is correct
4 Correct 64 ms 35996 KB Output is correct
5 Correct 65 ms 36024 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 84 ms 50768 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 7256 KB Output is correct
2 Incorrect 34 ms 15196 KB Output isn't correct
3 Halted 0 ms 0 KB -