Решение Codechef XORMIN (апрель 2019 Long Challenge 2019) - PullRequest
0 голосов
/ 16 апреля 2019

Я сейчас задаю этот вопрос на codechef. Я получаю RE (Runtime Error) для некоторых тестовых случаев.

Это логика, которую я реализовал: -

  1. Найти тур Эйлера и создать массив (ar)

  2. Каждый файл хранит свои дочерние элементы ,imumVertex и maxStartTime.

  3. trie [i] сохраняет значения от 1 до i в ар.

  4. Создание trie [i + 1] из trie [i], используя постоянство

  5. Для запроса (вершина, k) найдите max xor в дереве [индекс второго вхождения вершины в ar]

Код: -

#include <bits/stdc++.h>
using namespace std;
typedef long in;
#define lcm(a,b) ((a*b)/__gcd(a,b))
#define max(a,b) ((a)>(b)?(a):(b))
#define vi vector<in>
#define vvi vector<vector<in> >
#define vpi vector<pair<in,in> >
#define pb push_back
#define mp make_pair
#define pii pair<in,in>
#define fi first
#define se second
#define lb lower_bound
#define ub upper_bound
#define fio ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)

const in maxn=200005;
vector<in> adj[maxn];
vector<in> val(maxn);
vector<in> ar;
vector<pii> tme(maxn,mp(0,0));
vector<in> flag(maxn);
struct trie
{
    trie* arr[2];
    in minver,mst;//minimumVertex,maxStartTime
    trie() {
        arr[0]=arr[1]=NULL;
        minver=maxn;
        mst=0;
    }
};
vector<trie*> ptries(2*maxn);

//persistent trie
trie* insert(trie* root,in ver)
{
    trie* newroot=new trie();
    trie* source=newroot;
    in v=val[ver];
    in st=tme[ver].fi;
    trie* temp=root;
    for(in i=19; i>=0; i--)
    {
        bool bit=v&(1<<i);
        newroot->mst=max(newroot->mst,st);
        if(temp!=NULL)
        {
            newroot->arr[!bit]=temp->arr[!bit];
            temp=temp->arr[bit];
        }
        newroot->arr[bit]=new trie();
        newroot=newroot->arr[bit];
    }
    newroot->mst=max(newroot->mst,st);
    newroot->minver=min(newroot->minver,ver);
    return source;
}
//euler tour
void dfs(in i,in p)
{
    ar.pb(i);
    for(in j:adj[i])
        if(j!=p)
            dfs(j,i);
    ar.pb(i);
}

pii querytrie(in ver,in k)
{
    trie* root=ptries[tme[ver].se];
    in ans=0,v=k;
    trie* temp=root;
    for(in i=19; i>=0; i--)
    {
        bool bit=v&(1<<i);
        if(temp->arr[!bit]!=NULL && (temp->arr[!bit]->mst)>=tme[ver].fi)//opposite bit there and maxStartTime >=startTime of ver
        {
            ans=ans|(1<<i);
            temp=temp->arr[!bit];
        }
        else
            temp=temp->arr[bit];
    }
    return {temp->minver,ans};
}

int main() {
    // your code goes here
    in t;
    cin>>t;
    while(t--)
    {
        ar.clear();
        ptries.clear();
        val.clear();
        for(in i=0; i<maxn; i++)
        {
            adj[i].clear();
            tme[i]=mp(0,0);
            flag[i]=0;
        }
        in n,q;
        cin>>n>>q;
        for(in i=1; i<=n; i++)
            cin>>val[i];
        for(in i=1; i<n; i++)
        {
            in a,b;
            cin>>a>>b;
            adj[a].pb(b);
            adj[b].pb(a);
        }
        dfs(1,0);
        for (int i = 0; i < 2*n; i++) {
            if (tme[ar[i]].fi == 0)
                tme[ar[i]].fi = i+1;
            else
                tme[ar[i]].se = i+1;
        }
        ptries[1]=insert(new trie(),ar[0]);
        in j=0;
        for(in i=1; i<2*n; i++)
        {
            if(flag[ar[i]])
            {
                ptries[i+1]=ptries[i];
            }
            else
            {
                flag[ar[i]]=1;
                ptries[i+1]=insert(ptries[i],ar[i]);
            }

        }
        in xl=0,vl=0;
        for(in i=1; i<=q; i++)
        {
            in a,b;
            cin>>a>>b;
            in v=a^vl,k=b^xl;
            auto pp=querytrie(v,k);
            cout<<pp .fi<<" "<<pp.se<<endl;
            xl=pp.se;
            vl=pp.fi;
        }
    }
    return 0;
}

Я не думаю, что это из-за дополнительного использования памяти. Вероятно, ссылаясь на некоторую нераспределенную память или что-то еще.

Пожалуйста, помогите мне выявить недостатки в коде.

...