Submission #1329717

#TimeUsernameProblemLanguageResultExecution timeMemory
1329717Zbyszek99Circuit 2 (JOI25_circuit2)C++20
100 / 100
128 ms1560 KiB
#include "circuit.h"
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#define ll long long
#define ld long double
#define ull unsigned long long
#define ff first
#define ss second
#define pii pair<int,int>
#define pll pair<long long, long long>
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
#define rep(i, b) for(int i = 0; i < (b); ++i)
#define rep2(i,a,b) for(int i = a; i <= (b); ++i)
#define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c)
#define count_bits(x) __builtin_popcountll((x))
#define all(x) (x).begin(),(x).end()
#define siz(x) (int)(x).size()
#define forall(it,x) for(auto& it:(x))
using namespace __gnu_pbds;
using namespace std;
typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());}
//ll los(ll a, ll b) {return a + (mt() % (b-a+1));}
const int INF = 1e9+50;
const ll INF_L = 1e18+40;
const ll MOD = 1e9+7;

const int block = 64;
int ans[8001];
vi sons[16001];
int in_vert[16001];
bool is_in[8001];
int P[16001];
int max_path[16001];
int n;

void dfs_zero(int v)
{
    if(v >= n)
    {
        in_vert[v] ^= 1;
        return;
    }
    forall(it,sons[v]) dfs_zero(it);
}

bool try_set(vi x)
{
    rep(i,n) is_in[i] = 0;
    forall(it,x) is_in[it] = 1;
    rep(i,n) in_vert[i] = 0;
    rep2(i,n,n*2) in_vert[i] = 1;
    rep(i,n)
    {
        if(ans[i] == 1)
        {
            in_vert[i] ^= 1;
            in_vert[sons[i][0]] ^= 1;
            in_vert[sons[i][1]] ^= 1;
        }
    }
    forall(it,x)
    {
        in_vert[it] ^= 1;
        in_vert[sons[it][0]] ^= 1;
        in_vert[sons[it][1]] ^= 1;
        if(!is_in[sons[it][0]]) dfs_zero(sons[it][0]);
        else dfs_zero(sons[it][1]);
    }
    string q;
    rep(i,n*2+1) if(in_vert[i]) q += "1"; else q += "0";
    return !((bool)query(q));
}

void dfs_path(int v)
{
    max_path[v] = 0;
    forall(it,sons[v])
    {
        dfs_path(it);
        max_path[v] = max(max_path[v],max_path[it]);
    }
    if(v < n) max_path[v]++;
}

string solve(int N, int R, vi U, vi V) 
{
    n = N;
    rep2(i,n,n*2) sons[i] = {};
    rep(i,n) 
    {
        ans[i] = -1;
        sons[i] = {U[i],V[i]};
        P[U[i]] = i;
        P[V[i]] = i;
    }
    int know_cnt = 0;
    vi roots;
    vi roots2;
    while(know_cnt < n)
    {
        roots = {};
        rep(i,n) if(ans[i] == -1 && (P[i] == i || ans[P[i]] != -1)) roots.pb(i);
        forall(it,roots) dfs_path(it);
        vi group;
        while(siz(roots) != 0)
        {
            forall(it,roots) group.pb(it);
            roots2 = {};
            forall(it,roots)
            {
                pii best = {-1,-1};
                forall(it2,sons[it]) if(it2 < n) best = max(best,{max_path[it2],it2});
                if(best.ss != -1) roots2.pb(best.ss);
            }
            swap(roots,roots2);
        }
        while(siz(group) > block) group.pop_back();
        if(!try_set(group))
        {
            know_cnt += siz(group);
            forall(it,group) ans[it] = 0;
            continue;
        }
        int l = 0;
        int r = siz(group)-2;
        int ans2 = siz(group)-1;
        while(l <= r)
        {
            int mid = (l+r)/2;
            vi g2;
            rep(i,mid+1) g2.pb(group[i]);
            if(try_set(g2))
            {
                ans2 = mid;
                r = mid-1;
            }
            else
            {
                l = mid+1;
            }
        }
        know_cnt += ans2+1;
        rep(i,ans2) ans[group[i]] = 0;
        ans[group[ans2]] = 1;
    }
    string ans2;
    rep(i,n) if(ans[i] == 1) ans2 += "|"; else ans2 += "&";
    return ans2;
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...