• AT4831 [ABC155F] Perils in Parallel 生成树


    题意:

    戳这里

    分析:

    首先我们先把区间操作转化一下,因为区间操作的复杂度太高

    我们把每一位上的值记为它和它前一位的异或值

    这样 ([l,r]) 的区间翻转等价于 (l,r+1) 的单点异或,而我们的目标还是使得所有位置上的值为 (0)

    像这样的点对关系我们可以看成 (l,r+1) 之间连接了一条无向边,我们要做的就是选择一些边,将两端的点值取反,使得每一个点的值为 0

    然后我们建出图之后会发现,这是一个不连通的一般图,但是我们发现可以将这幅图转化为一些森林,因为如果选中的边成环了那么等价于没有选,所以每一个连通块都是一棵树,那么我们的问题转化为对于每一棵树选一些边,最后使得树上所有点的值为 (0) ,直接树形DP

    对于节点 (u) 如果他的一个儿子值为 (1) 那么这条边必须选,同时对 (u)(v) 的值取反,如果为 (0) 那么不选

    最后如果根节点的值为 (1) 那么无解

    tip: 因为区间操作转化为单点操作的时候会出现 (n+1) 点,但实际上 (n+1) 点的点值不存在,所以它为 (0,1) 都不影响结果,所以我们可以钦定 (n+1) 所在的连通块以 (n+1) 为根,不论结果如何不用管

    代码:

    #include<bits/stdc++.h>
    #define pii pair<int,int>
    #define mk(x,y) make_pair(x,y)
    #define fir first
    #define sec second
    #define inl inline
    #define reg register
    #define pb push_back
    
    using namespace std;
    
    namespace zzc
    {
        inl int read()
        {
            int x=0,f=1;char ch=getchar();
            while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
            while(isdigit(ch)) {x=x*10+ch-48;ch=getchar();}
            return x*f;
        }
    
        const int maxn = 2e5+5;
        int n,m,cnt;
        pii p[maxn];
        int pos[maxn],fa[maxn],head[maxn];
        bool vis[maxn],sta[maxn];
        vector<int> ans;
    
        struct edge
        {
            int to,nxt,id;
        }e[maxn<<2];
    
        inl void add(int u,int v,int w)
        {
            e[++cnt].to=v;
            e[cnt].id=w;
            e[cnt].nxt=head[u];
            head[u]=cnt;
        }
    
        int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}
        
        inl bool connect(int x,int y)
        {
            int fx=find(x),fy=find(y);
            if(fx==fy) return true;
            fa[fy]=fx;
            return false;
        }
    
        bool dfs(int u)
        {
            bool res=sta[u];
            vis[u]=true;
            for(int i=head[u];i;i=e[i].nxt)
            {
                int v=e[i].to;
                if(vis[v]) continue;
                bool tmp=dfs(v);
                if(tmp) ans.pb(e[i].id);
                res^=tmp;
            }
            return res;
        }
    
        void work()
        {
            int l,r;
            n=read();m=read();
            for(int i=1;i<=n+1;i++) fa[i]=i;
            for(int i=1;i<=n;i++) p[i].fir=read(),p[i].sec=read();
            sort(p+1,p+n+1);
            for(int i=1;i<=n;i++) pos[i]=p[i].fir,sta[i]=p[i].sec;
            for(int i=n;i;i--) sta[i]^=sta[i-1];
            for(int i=1;i<=m;i++)
            {
                l=read();r=read();
                l=lower_bound(pos+1,pos+n+1,l)-pos;
                r=upper_bound(pos+1,pos+n+1,r)-pos;
                if(!connect(l,r)) add(l,r,i),add(r,l,i);
            }
            dfs(n+1);
            for(int i=1;i<=n;i++)
            {
                if(vis[i]) continue;
                if(dfs(i))
                {
                    puts("-1");
                    return ;
                }
            }
            sort(ans.begin(),ans.end());
            printf("%d
    ",ans.size());
            for(int i=0,j=ans.size();i<j;i++) printf("%d ",ans[i]);
        }
    
    }
    
    int main()
    {
        zzc::work();
        return 0;
    }
    
    
  • 相关阅读:
    leetcode Power of Two
    leetcode Merge Two Sorted Lists
    Mac linux 安装memcached服务 用法
    Vsftp配置都没有问题 连接不上 530 Login incorrect 解决方法
    mysql 远程连接不上 %用户已经添加了
    Centos yum 安装mysql报错 No package mysql-server available.
    Linux 查询程序安装路径 是否安装
    php报错 Call to undefined function mb_stripos()
    mac编译openssl扩展报错 openssl.c:44:10: fatal error: 'openssl/evp.h' file not found
    在安装mysqli的时候,出现error: ext/mysqlnd/mysql_float_to_double.h: No such file or direc
  • 原文地址:https://www.cnblogs.com/youth518/p/14329798.html
Copyright © 2020-2023  润新知