ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P6684 [BalticOI 2020 Day1] 小丑 题解

2022-05-19 09:00:38  阅读:151  来源: 互联网

标签:zxc fa int 题解 top P6684 Day1 dep siz


不难发现对于一个特定的 \(\text{l}\) 而言,\(\text{r}\) 的答案具有单调性。

所以就可以很自然的想到二分。

由于需要对所有的 \(\text{l}\) 都进行统计答案。

只用普通的二分复杂度会炸掉,所以就可以想到使用整体二分。

思路

首先考虑如何判断奇环。

对于这部分内容,可以考虑一边加边,一边判断奇环。

使用可撤销并查集维护。

如果此时加的边在同一连通块内,直接判断奇偶。

若不在同一个连通块则合并两个连通块,更新奇偶。

至于整体二分的内容可以直接套板子了。

Code

#include <bits/stdc++.h>
using namespace std;

const int N = 200010;

int n , m , q , top , ans , fa[N] , dep[N] , val[N] , siz[N] , stk[N] , sum[N];
pair<int , int> e[N];

#define fir first
#define sec second
void solve(int l , int r , int L , int R);

inline int read()
{
    int asd = 0 , qwe = 1; char zxc;
    while(!isdigit(zxc = getchar())) if(zxc == '-') qwe = -1;
    while(isdigit(zxc)) asd = asd * 10 + zxc - '0' , zxc = getchar();
    return asd * qwe;
}

inline int gf(int x)
{
    if(x == fa[x])
        return x;
    int rt = gf(fa[x]);
    dep[x] = dep[fa[x]] ^ val[x];
    return rt;
}

inline void calc(int x , int y)
{       
    if(!x) return;
    int fx = gf(x) , fy = gf(y);
    if(fx == fy)
        return ans |= (dep[x] == dep[y]) , void();
    bool flag = (dep[x] == dep[y]);
    x = fx , y = fy;
    if(siz[x] < siz[y]) swap(x , y);
    fa[y] = x , val[y] = flag;
    siz[x] += siz[y] , stk[++top] = y;
}

inline void del(int x)
{
    while(top > x)
    {
        int y = stk[top--];
        siz[fa[y]] -= siz[y];
        fa[y] = y , val[y] = dep[y] = 0;
    }
}

inline void cl()
{
    ans = top = 0;
    for(int i = 1;i <= n;i++)
        fa[i] = i , dep[i] = val[i] = 0 , siz[i] = 1;
}

int main()
{
    n = read() , m = read() , q = read() , cl();
    for(int i = 1;i <= m;i++)
    {
        e[i].fir = read() , e[i].sec = read();
    }
    int x = 0;
    for(int i = 1;i <= m;i++)
    {
        calc(e[i].fir , e[i].sec);
        if(ans)
        {
            for(int j = i;j <= m;j++)
                sum[j] = m + 1;
            x = i;
            break;
        }
    }
    if(!ans)
    {
        while(q--) puts("NO");
        return 0;
    }
    cl();
    solve(0 , x - 1 , 1 , m + 1);
    for(int i = 1;i <= q;i++)
    {
        int l = read() , r = read();
        puts(sum[l - 1] <= r ? "NO" : "YES");
    }
    return 0;
}

inline void solve(int l , int r , int L , int R)
{
    if(L + 1 == R || l > r)
    {
        for(int i = l;i <= r;i++)   
            sum[i] = L;
        return;
    }
    int mid = (L + R) / 2 , ltop = top , lans = ans;
    for(int i = R - 1;i >= mid && !ans;i--)
        calc(e[i].fir , e[i].sec);
    int topl = top , ansl = ans , lmid = min(r , mid - 1);
    for(int i = l;i <= lmid;i++)
    {
        calc(e[i].fir , e[i].sec);
        if(ans)
        {
            lmid = i - 1;
            break;
        }
    }
    ans = ansl , del(topl);
    solve(l , lmid , L , mid);
    ans = lans , del(ltop);
    for(int i = l;i <= lmid;i++)
        calc(e[i].fir , e[i].sec);
    solve(lmid + 1 , r , mid , R);
    ans = lans , del(ltop);
}

标签:zxc,fa,int,题解,top,P6684,Day1,dep,siz
来源: https://www.cnblogs.com/mfeitveer/p/16287228.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有