Submission #1294368

#TimeUsernameProblemLanguageResultExecution timeMemory
1294368HoriaHaivasSpring cleaning (CEOI20_cleaning)C++20
100 / 100
125 ms26892 KiB
#include<bits/stdc++.h>
#define debug(x) cerr << #x << " " << x << "\n"
#define debugs(x) cerr << #x << " " << x << " "
#pragma GCC optimize("Ofast")
#define int long long

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int range_rng(int l, int r)
{
    return uniform_int_distribution<int>(l,r)(rng);
}

vector<int> nodes[200005];
map<int,int> cnt;
int h[200005];
int u[200005];
int p[200005];
bool is_leaf[200005];
int leaves[200005];
int sz[200005];
int heavychild[200005];
int pathend[200005];
int stamp[200005];
int revstamp[200005];
int timer,root,ans,n;
bool ok;

struct Node
{
    int sumodd;
    int sumeven;
    int lazy;
};

class AINT
{
public:

    Node aint[800005];

    Node combine(Node a, Node b)
    {
        Node c;

        c.sumeven=0;
        c.sumodd=0;

        c.sumeven+=a.sumeven;
        c.sumodd+=a.sumodd;


        c.sumeven+=b.sumeven;
        c.sumodd+=b.sumodd;
        c.lazy=0;
        ///lazy e mereu 0
        return c;
    }

    void prop(int val, int l, int r)
    {
        if (aint[val].lazy==0)
            return;
        if (aint[val].lazy%2==1)
        swap(aint[val].sumeven,aint[val].sumodd);
        if (l!=r)
        {
            aint[val*2].lazy+=aint[val].lazy;
            aint[val*2+1].lazy+=aint[val].lazy;
        }
        aint[val].lazy=0;
    }

    void build(int l, int r, int val)
    {
        if (l==r)
        {
            aint[val].lazy=0;
            aint[val].sumeven=0;
            aint[val].sumodd=0;
            if (leaves[revstamp[l]]%2==1)
                aint[val].sumodd=1;
            else
                aint[val].sumeven=1;
            return;
        }
        int mid;
        mid=(l+r)/2;
        build(l,mid,val*2);
        build(mid+1,r,val*2+1);
        aint[val]=combine(aint[val*2],aint[val*2+1]);
    }

    void flip(int l, int r, int val, int qa, int qb)
    {
        prop(val,l,r);
        if (qa<=l && r<=qb)
        {
            aint[val].lazy+=1;
            return;
        }
        int mid;
        mid=(l+r)/2;
        if (qa<=mid)
            flip(l,mid,val*2,qa,qb);
        if (qb>mid)
            flip(mid+1,r,val*2+1,qa,qb);
        prop(val*2,l,mid);
        prop(val*2+1,mid+1,r);
        aint[val]=combine(aint[val*2],aint[val*2+1]);
    }

    void add_leaf(int parent)
    {
        if (is_leaf[parent])
            parent=p[parent];
        while (pathend[parent]!=root)
        {
            flip(1,n,1,stamp[pathend[parent]],stamp[parent]);
            parent=p[pathend[parent]];
        }
        flip(1,n,1,stamp[pathend[parent]],stamp[parent]);
    }

    void remove_leaf(int parent)
    {
        if (is_leaf[parent])
            parent=p[parent];
        while (pathend[parent]!=root)
        {
            flip(1,n,1,stamp[pathend[parent]],stamp[parent]);
            parent=p[pathend[parent]];
        }
        flip(1,n,1,stamp[pathend[parent]],stamp[parent]);
    }

    int query(int l, int r, int val, int qa, int qb)
    {
        prop(val,l,r);
        if (qa<=l && r<=qb)
        {
            return aint[val].sumeven;
        }
        int mid,ans;
        ans=0;
        mid=(l+r)/2;
        if (qa<=mid)
            ans+=query(l,mid,val*2,qa,qb);
        if (qb>mid)
            ans+=query(mid+1,r,val*2+1,qa,qb);
        return ans;
    }

} hevi;

void dfs(int node, int parent)
{
    leaves[node]=0;
    sz[node]=1;
    if (nodes[node].size()==1)
    {
        is_leaf[node]=1;
        leaves[node]=1;
        return;
    }
    int mx;
    mx=0;
    for (auto x : nodes[node])
    {
        if (x!=parent)
        {
            p[x]=node;
            h[x]=h[node]+1;
            dfs(x,node);
            leaves[node]+=leaves[x];
            sz[node]+=sz[x];
            if (sz[x]>sz[mx])
            {
                mx=x;
            }
        }
    }
    heavychild[node]=mx;
    if (leaves[node]%2==1)
        leaves[node]=1;
    else
        leaves[node]=2;
}

void heavy_order(int node, int parent, int capat)
{
    timer++;
    stamp[node]=timer;
    revstamp[timer]=node;
    pathend[node]=capat;
    if (heavychild[node]==0)
        return;
    heavy_order(heavychild[node],node,capat);
    for (auto x : nodes[node])
    {
        if (x!=parent && x!=heavychild[node])
        {
            heavy_order(x,node,x);
        }
    }
}

signed main()
{
    /*
    ifstream fin("arbore.in");
    ofstream fout("arbore.out");
    */
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int q,i,j,uu,v,d,total_leaves;
    cin >> n >> q;
    for (i=1; i<=n-1; i++)
    {
        cin >> uu >> v;
        nodes[uu].push_back(v);
        nodes[v].push_back(uu);
    }
    for (i=1; i<=n; i++)
    {
        if (nodes[i].size()!=1)
        {
            root=i;
            break;
        }
    }
    h[root]=0;
    ans=0;
    dfs(root,-1);
    total_leaves=leaves[root];
    timer=0;
    heavy_order(root,-1,root);
    hevi.build(1,n,1);
    for (i=1; i<=q; i++)
    {
        ans=0;
        cin >> d;
        for (j=1; j<=d; j++)
        {
            cin >> u[j];
            ans++;
            if (nodes[u[j]].size()!=1)
            {
                total_leaves++;
                hevi.add_leaf(u[j]);
            }
            nodes[u[j]].push_back(n+j);
            if (is_leaf[u[j]])
            {
                if (nodes[u[j]].size()%2==0 && nodes[u[j]].size()>=4)
                    ans--;
                else if (nodes[u[j]].size()%2==1)
                    ans++;
            }
        }
        if (total_leaves%2==0)
        {
            ans+=n-1;
            ans+=hevi.query(1,n,1,1,n);
            //debug(hevi.query(1,n,1,1,n));
            ans-=hevi.query(1,n,1,stamp[root],stamp[root]);
            //debug(hevi.query(1,n,1,stamp[root],stamp[root]));
            cout << ans << "\n";
        }
        else
            cout << "-1\n";
        for (j=1; j<=d; j++)
        {
            nodes[u[j]].pop_back();
            if (nodes[u[j]].size()!=1)
            {
                hevi.remove_leaf(u[j]);
                total_leaves--;
            }
        }
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...