1 条题解

  • 0
    @ 2024-11-23 18:58:14

    是这样的,在 2024 CSP-S2024~\text{CSP-S} 中,先看T1,贪心秒了(就是这次 2024年第二届科技节信息竞赛 的T2 吧)。

    然后开 T2,这不就物理题吗,打了差不多半个小时打出来了,然后测大样例,然后发现全对。

    这时候我突然发现自己一个细节不对,进入 2 阶段,调试。结果改成当时认为的正确方法时,发现倒数第二个大样例错了,崩溃,调代码,调了好长时间没调出来,先做 T3。

    当时 T3 但凡做的时间久一点就做出来了,是一个简单的 dp,但是当时只打了个 20 分的暴力。

    然后又回去调 T2,到最后都没调出来,出来后以为自己只有 160 分了,直接 emo 了。所以说心情异常低落。(其实当时是把 -1 写成 0 了。但是最后 CCF 数据过水没把我卡掉(喜)。

    晚上打 cf,结果同机房大佬加了 354 分,我只加了 35 分,我还是菜啊。

    对了,忘记说题解了。挺裸一题,感觉没啥好写的。

    我在题目最后一行藏了个东西:对于 100%100\% 的测试点,保证 m=n1m=n-1,所以是一个树,那么在树上的操作就很简单了。

    线段树 + 树链剖分秒了。

    其实代码不是很长,主要是我的习惯硬生生把 std 拉长了。

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 1e2+5;
    
    int n,m,q;
    int a[MAXN];
    int ca[MAXN];
    vector<int> e[MAXN];
    
    struct Node
    {
        int lft0,lft1;
        int mid0,mid1;
        int rit0,rit1;
        int sum0,sum1;
        Node operator+(const Node &x)const
        {
            Node tmp = {0,0,0,0,0,0};
            if(!sum1) tmp.lft0 = lft0 + x.lft0;
            else tmp.lft0 = lft0;
            if(!sum0) tmp.lft1 = lft1 + x.lft1;
            else tmp.lft1 = lft1;
    
            tmp.mid0 = max({mid0,x.mid0,rit0+x.lft0});
            tmp.mid1 = max({mid1,x.mid1,rit1+x.lft1});
    
            if(!x.sum1) tmp.rit0 = rit0 + x.rit0;
            else tmp.rit0 = x.rit0;
            if(!x.sum0) tmp.rit1 = rit1 + x.rit1;
            else tmp.rit1 = x.rit1;
    
            tmp.sum0 = sum0 + x.sum0;
            tmp.sum1 = sum1 + x.sum1;
    
            return tmp;
        }
    
        void turn()
        {
            swap(lft0,lft1);
            swap(mid0,mid1);
            swap(rit0,rit1);
            swap(sum0,sum1);
        }
    
        void init()
        {
            lft0 = lft1 = mid0 = mid1 = rit0 = rit1 = sum0 = sum1 =0;
        }
    };
    
    struct SegmentTree
    {
        #define lp p<<1
        #define rp p<<1|1
        Node tree[MAXN<<2];
        bool lt0[MAXN<<2],lt1[MAXN<<2];
        bool ltt[MAXN<<2];
        int nums[MAXN];
        int len;
    
        void push_up(int p)
        {
            tree[p] = tree[lp] + tree[rp];
        }
    
        void push_down(int s,int t,int p)
        {
            int mid = (s + t) >> 1;
            if(lt0[p])
            {
                lt0[lp] = lt0[rp] = true;
                lt1[lp] = lt1[rp] = ltt[lp] = ltt[rp] = false;
    
                tree[lp].lft0 = tree[lp].mid0 = tree[lp].rit0 = tree[lp].sum0 = mid - s + 1;
                tree[rp].lft0 = tree[rp].mid0 = tree[rp].rit0 = tree[rp].sum0 = t - mid;
    
                tree[lp].lft1 = tree[lp].mid1 = tree[lp].rit1 = tree[lp].sum1 = 0;
                tree[rp].lft1 = tree[rp].mid1 = tree[rp].rit1 = tree[rp].sum1 = 0;
    
                lt0[p] = false;
                return;
            }
            if(lt1[p])
            {
                lt1[lp] = lt1[rp] = true;
                lt0[lp] = lt0[rp] = ltt[lp] = ltt[rp] = false;
    
                tree[lp].lft0 = tree[lp].mid0 = tree[lp].rit0 = tree[lp].sum0 = 0;
                tree[rp].lft0 = tree[rp].mid0 = tree[rp].rit0 = tree[rp].sum0 = 0;
    
                tree[lp].lft1 = tree[lp].mid1 = tree[lp].rit1 = tree[lp].sum1 = mid - s + 1;
                tree[rp].lft1 = tree[rp].mid1 = tree[rp].rit1 = tree[rp].sum1 = t - mid;
    
                lt1[p] = false;
                return;
            }
            if(ltt[p])
            {
                if(lt0[lp] || lt1[lp]) swap(lt0[lp],lt1[lp]);
                else ltt[lp] ^= true;
                if(lt0[rp] || lt1[rp]) swap(lt0[rp],lt1[rp]);
                else ltt[rp] ^= true;
    
                tree[lp].turn();
                tree[rp].turn();
                
                ltt[p] = false;
                return;
            }
        }
    
        void build(int s,int t,int p)
        {
            tree[p].init();
            if(s == t)
            {
                if(nums[s])
                {
                    tree[p] = Node{0,1,0,1,0,1,0,1};
                }
                else
                {
                    tree[p] = Node{1,0,1,0,1,0,1,0};
                }
                return;
            }
            int mid = (s + t) >> 1;
            build(s,mid,lp);
            build(mid+1,t,rp);
            push_up(p);
        }
    
        void set(int l,int r,int s,int t,int p,int k)
        {
            if(l <= s && t <= r)
            {
                int le = (t - s) + 1;
                ltt[p] = false;
                if(k == 0)
                {
                    lt1[p] = false;
                    tree[p].lft0 = tree[p].mid0 = tree[p].rit0 = tree[p].sum0 = le;
                    tree[p].lft1 = tree[p].mid1 = tree[p].rit1 = tree[p].sum1 = 0;
                    lt0[p] = true;
                }
                if(k == 1)
                {
                    lt0[p] = false;
                    tree[p].lft0 = tree[p].mid0 = tree[p].rit0 = tree[p].sum0 =0;
                    tree[p].lft1 = tree[p].mid1 = tree[p].rit1 = tree[p].sum1 = le;
                    lt1[p] = true;
                }
                return;
            }
            push_down(s,t,p);
            int mid = (s + t) >> 1;
            if(l <= mid) set(l,r,s,mid,lp,k);
            if(r > mid) set(l,r,mid+1,t,rp,k);
            push_up(p);  
        }
    
        void turn(int l,int r,int s,int t,int p)
        {
            if(l <= s && t <= r)
            {
                int le = (t - s) + 1;
                if(lt0[p] || lt1[p])
                {
                    swap(lt0[p],lt1[p]);
                }
                else ltt[p] ^= true;
                tree[p].turn();
                return;
            }
            push_down(s,t,p);
            int mid = (s + t) >> 1;
            if(l <= mid) turn(l,r,s,mid,lp);
            if(r > mid) turn(l,r,mid+1,t,rp);
            push_up(p); 
        }
    
        Node query(int l,int r,int s,int t,int p)
        {
            if(l <= s && t <= r)
            {
                return tree[p];
            }
            push_down(s,t,p);
            int mid = (s + t) >> 1;
            Node re;
            re.init();
            if(l <= mid)
            {
                re = query(l,r,s,mid,lp);
                if(r > mid) re = re + query(l,r,mid+1,t,rp);
            }
            else if(r > mid) re = query(l,r,mid+1,t,rp);
            return re;
        }
    
        void Build(int len,int nums[])
        {
            this->len = len;
            for(int i = 1;i <= len;i++) this->nums[i] = nums[i];
            build(1,len,1);
        }
        void Set(int l,int r,int k)
        {
            set(l,r,1,len,1,k);
        }
        void Turn(int l,int r)
        {
            turn(l,r,1,len,1);
        }
        Node Query(int l,int r)
        {
            return query(l,r,1,len,1);
        }
    
        #undef lp
        #undef rp
    }tree;
    
    int fa[MAXN],dep[MAXN],siz[MAXN],hson[MAXN];
    void dfs1(int f,int u,int d)
    {
        dep[u] = d;
        siz[u] = 1;
        for(int i = e[u].size()-1;i >= 0;i--)
        {
            int v = e[u][i];
            if(v == f) continue;
            fa[v] = u;
            dfs1(u,v,d+1);
            siz[u] += siz[v];
            if(siz[hson[u]] < siz[v]) hson[u] = v;
        }
    }
    
    int dfn[MAXN],rnk[MAXN],top[MAXN],dfncnt;
    void dfs2_init()
    {
        for(int i = 1;i <= n;i++) top[i] = i;
    }
    void dfs2(int u,int t)
    {
        top[u] = t;
        dfn[u] = ++dfncnt;
        ca[dfncnt] = a[u];
        rnk[dfn[u]] = u;
        if(hson[u]) dfs2(hson[u],t);
        for(int i = e[u].size()-1;i >= 0;i--)
        {
            int v = e[u][i];
            if(v == hson[u] || v == fa[u]) continue;
            dfs2(v,v);
        }
    }
    
    int main()
    {
        scanf("%d%d%d",&n,&m,&q);
        for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
        for(int i = 1;i <= m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            e[u].push_back(v);
            e[v].push_back(u);
        }
        
        dfs1(0,1,1);
        dfs2_init();
        dfs2(1,1);
        tree.Build(n,ca);
    
        while(q--)
        {
            int op,x,y;
            scanf("%d%d%d",&op,&x,&y);
            if(op == 1)
            {
                while(top[x] != top[y])
                {
                    if(dep[top[x]] < dep[top[y]]) swap(x,y);
                    tree.Set(dfn[top[x]],dfn[x],1);
                    x = fa[top[x]];
                }
                if(dep[x] > dep[y]) swap(x,y);
                tree.Set(dfn[x],dfn[y],1);
            }
            if(op == 2)
            {
                while(top[x] != top[y])
                {
                    if(dep[top[x]] < dep[top[y]]) swap(x,y);
                    tree.Set(dfn[top[x]],dfn[x],0);
                    x = fa[top[x]];
                }
                if(dep[x] > dep[y]) swap(x,y);
                tree.Set(dfn[x],dfn[y],0);
            }
            if(op == 3)
            {
                while(top[x] != top[y])
                {
                    if(dep[top[x]] < dep[top[y]]) swap(x,y);
                    tree.Turn(dfn[top[x]],dfn[x]);
                    x = fa[top[x]];
                }
                if(dep[x] > dep[y]) swap(x,y);
                tree.Turn(dfn[x],dfn[y]);
            }
            if(op == 4)
            {
                Node ansx,ansy;
                ansx.init(),ansy.init();
                while(top[x] != top[y])
                {
                    if(dep[top[x]] >= dep[top[y]])
                    {
                        ansx = tree.Query(dfn[top[x]],dfn[x]) + ansx;
                        x = fa[top[x]];
                    }
                    else
                    {
                        ansy = tree.Query(dfn[top[y]],dfn[y]) + ansy;
                        y = fa[top[y]];
                    }
                }
                if(dep[x] > dep[y]) ansx = tree.Query(dfn[y],dfn[x]) + ansx;
                else ansy = tree.Query(dfn[x],dfn[y]) + ansy;
    
                swap(ansy.lft0,ansy.rit0);
                swap(ansy.lft1,ansy.rit1);
                Node tmp = ansy + ansx;
                printf("%d\n",tmp.mid0);
            }
        }
        
        return 0;
    }
    

    禁止抄代码

    信息

    ID
    961
    时间
    1000ms
    内存
    256MiB
    难度
    1
    标签
    递交数
    4
    已通过
    1
    上传者