QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#558700#8012. Jumping Lightsrqoi031WA 0ms20496kbC++209.2kb2024-09-11 17:48:412024-09-11 17:48:41

Judging History

This is the latest submission verdict.

  • [2024-09-11 17:48:41]
  • Judged
  • Verdict: WA
  • Time: 0ms
  • Memory: 20496kb
  • [2024-09-11 17:48:41]
  • Submitted

answer

#include<stdio.h>
#include<algorithm>
#include<chrono>
#include<random>
#include<vector>
#include<utility>
typedef unsigned int uint;
// std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
std::mt19937 rng(1);
struct edge {
    int v,next;
};
edge e[600005];
int en,last[300005];
inline void add_edge(const int &u,const int &v) {
    e[++en]={v,last[u]},last[u]=en;
}
int fa[300005],size[300005];
void dfs(const int &u) {
    size[u]=1;
    for(int i=last[u];i;i=e[i].next) {
        const int &v(e[i].v);
        if(v==fa[u]) {
            continue;
        }
        fa[v]=u,dfs(v);
        size[u]+=size[v];
    }
}
int lsize[300005];
inline void find_leaves(const int &n) {
    for(int u=1;u<=n;u++) {
        for(int i=last[u];i;i=e[i].next) {
            const int &v(e[i].v);
            lsize[u]+=size[v]==1;
        }
    }
}
std::vector<int> stk;
struct data {
    std::vector<std::pair<int,int>> upd;
    struct leaves {
        struct element {
            int val,time;
        };
        element ele[300005];
        struct segment {
            int tag;
            int time;
            int cnt;
        };
        segment seg[300005];
        int total;
        inline void init(const int &n) {
            for(int i=1;i<=n;i++) {
                ele[i]={0,0};
                seg[i]={0,0,0};
            }
            total=0;
        }
        inline int query(const int &x,const int &y) {
            return ele[y].time>=seg[x].time?ele[y].val:seg[x].tag;
        }
        inline int modify(const int &x,const int &y,const int &v) {
            if(v==query(x,y)) {
                return 0;
            }
            ele[y].val=v,ele[y].time=seg[x].time;
            seg[x].cnt+=v?1:-1,total+=v?1:-1;
            return v?1:-1;
        }
        inline int query_all(const int &x) {
            return seg[x].cnt;
        }
        inline void modify_all(const int &x,const int &v) {
            total-=seg[x].cnt;
            seg[x].tag=v,++seg[x].time;
            seg[x].cnt=v?lsize[x]:0;
            total+=seg[x].cnt;
        }
    }A;
    struct nonleaves {
        int val[300005],cnt;
        inline void init(const int &n) {
            std::fill(val+1,val+n+1,0),cnt=0;
        }
        inline void modify(const int &x,const int &v) {
            if(v!=val[x]) {
                val[x]=v,cnt+=v?1:-1;
            }
        }
        inline int query(const int &x) {
            return val[x];
        }
    }B;
    struct sons {
        struct node {
            uint val;
            int fa;
            union {
                struct {
                    int ls,rs;
                };
                int son[2];
            };
            int size;
        };
        node tr[300005];
        inline int son_type(const int &x) {
            return tr[tr[x].fa].rs==x;
        }
        inline void push_up(const int &x) {
            tr[x].size=tr[tr[x].ls].size+tr[tr[x].rs].size+1;
        }
        inline void rotate(const int &x) {
            const int y(tr[x].fa),z(tr[y].fa),k(son_type(x));
            tr[x].fa=z;
            if(z!=0) {
                tr[z].son[son_type(y)]=x;
            }
            tr[tr[y].son[k]=tr[x].son[k^1]].fa=y;
            tr[tr[x].son[k^1]=y].fa=x;
            push_up(y),push_up(x);
        }
        int root[300005];
        inline void init(const int &n) {
            for(int i=1;i<=n;i++) {
                tr[i]={rng(),0,0,0,1};
                root[i]=0;
            }
        }
        inline void insert(const int &x,const int &y) {
            if(root[x]==0) {
                return root[x]=y,void();
            }
            int z(root[x]);
            while(true) {
                if(y==z) {
                    return;
                }
                if(y<z) {
                    if(!tr[z].ls) {
                        tr[z].ls=y;
                        tr[y].fa=z;
                        break;
                    }
                    z=tr[z].ls;
                }
                else {
                    if(!tr[z].rs) {
                        tr[z].rs=y;
                        tr[y].fa=z;
                        break;
                    }
                    z=tr[z].rs;
                }
            }
            while(tr[y].fa!=0&&tr[y].val<tr[tr[y].fa].val) {
                rotate(y);
            }
            if(tr[y].fa==0) {
                root[x]=y;
            }
        }
        int merge(const int &x,const int &y) {
            if(x==0) {
                return y;
            }
            if(y==0) {
                return x;
            }
            if(tr[x].val<tr[y].val) {
                const int z(merge(tr[x].rs,y));
                tr[x].rs=z,tr[z].fa=x,push_up(x);
                return x;
            }
            const int z(merge(x,tr[y].ls));
            tr[y].ls=z,tr[z].fa=y,push_up(y);
            return y;
        }
        inline void reset(const int &x) {
            tr[x].fa=tr[x].ls=tr[x].rs=0,tr[x].size=1;
        }
        inline void erase(const int &x,const int &y) {
            const int z(merge(tr[y].ls,tr[y].rs));
            (y==root[x]?root[x]:tr[tr[y].fa].son[son_type(y)])=z;
            tr[z].fa=tr[y].fa;
            for(int i=tr[y].fa;i;i=tr[i].fa) {
                push_up(i);
            }
            reset(y);
        }
        void enumerate(const int &x) {
            if(tr[x].ls) {
                enumerate(tr[x].ls);
            }
            stk.emplace_back(x);
            if(tr[x].rs) {
                enumerate(tr[x].rs);
            }
        }
    }C;
    int sum;
    inline int check(const int &x) {
        return size[x]==1?A.query(fa[x],x):B.query(x);
    }
    inline int checkn(const int &x) {
        return A.query_all(x)+(fa[x]?B.query(fa[x]):0);
    }
    inline void init(const int &n) {
        upd.clear();
        A.init(n),B.init(n),C.init(n);
        for(int i=1;i<=n;i++) {
            if(size[i]!=1) {
                C.insert(fa[i],i);
            }
        }
        sum=0;
    }
    inline void enumerate(const int &x) {
        if(C.root[x]) {
            C.enumerate(C.root[x]);
        }
    }
    inline void mark(const int &x) {
        if(size[x]==1) {
            sum+=A.modify(fa[x],x,1);
        }
        else if(B.query(x)==0) {
            ++sum;
            B.modify(x,1);
            if(__builtin_expect(fa[x]!=0,1)) {
                C.erase(fa[x],x);
            }
        }
    }
    inline void mark_leaves(const int &x) {
        sum-=A.query_all(x);
        A.modify_all(x,1);
        sum+=A.query_all(x);
    }
    inline void unmark(const int &x) {
        if(size[x]==1) {
            sum+=A.modify(fa[x],x,0);
        }
        else if(B.query(x)==1) {
            --sum;
            B.modify(x,0);
            if(__builtin_expect(fa[x]!=0,1)) {
                C.insert(fa[x],x);
            }
        }
    }
    inline void unmark_leaves(const int &x) {
        sum-=A.query_all(x);
        A.modify_all(x,0);
        sum+=A.query_all(x);
    }
};
data D[2];
int main() {
    int n,q;
    scanf("%d%d",&n,&q);
    for(int i=1;i<n;i++) {
        int u,v;
        scanf("%d%d",&u,&v);
        add_edge(u,v);
        add_edge(v,u);
    }
    dfs(1);
    find_leaves(n);
    D[0].init(n);
    D[1].init(n);
    int cur(0);
    const auto mark([&](const int &x)->void {
        D[cur].mark(x);
        D[cur^1].upd.emplace_back(x,1);
    });
    const auto unmark([&](const int &x)->void {
        D[cur].unmark(x);
        D[cur^1].upd.emplace_back(x,1);
        if(__builtin_expect(fa[x]!=0,1)) {
            D[cur^1].upd.emplace_back(fa[x],0);
        }
    });
    const auto spread([&]()->void {
        cur^=1;
        std::vector<std::pair<int,int>> vec;
        vec.swap(D[cur].upd);
        std::sort(vec.begin(),vec.end());
        vec.erase(std::unique(vec.begin(),vec.end()),vec.end());
        for(const auto &[x,k]:vec) {
            if(k==0) {
                if(D[cur^1].checkn(x)) {
                    mark(x);
                }
                else {
                    unmark(x);
                }
            }
            else if(k==1) {
                if(D[cur^1].check(x)) {
                    D[cur].mark_leaves(x);
                    if(__builtin_expect(fa[x]!=0,1)) {
                        mark(fa[x]);
                    }
                    stk.clear();
                    D[cur].enumerate(x);
                    for(const int &y:stk) {
                        mark(y);
                    }
                }
                else {
                    D[cur].unmark_leaves(x);
                }
            }
        }
    });
    const auto query([&]()->int {
        return D[cur].sum;
    });
    for(int i=1;i<=q;i++) {
        int op;
        scanf("%d",&op);
        if(op==0) {
            int x;
            scanf("%d",&x);
            unmark(x);
        }
        else if(op==1) {
            int x;
            scanf("%d",&x);
            mark(x);
        }
        else if(op==2) {
            spread();
        }
        printf("%d%c",query(),i==q?'\n':' ');
    }
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 20208kb

input:

8 8
1 2
2 3
2 4
1 5
5 6
5 7
5 8
1 1
2
2
0 1
0 3
0 4
0 5
2

output:

1 2 6 5 4 3 3 1

result:

ok 8 numbers

Test #2:

score: 0
Accepted
time: 0ms
memory: 20448kb

input:

4 5
1 2
1 3
2 4
1 2
2
0 4
2
2

output:

1 2 1 2 2

result:

ok 5 number(s): "1 2 1 2 2"

Test #3:

score: -100
Wrong Answer
time: 0ms
memory: 20496kb

input:

1000 1000
471 906
653 752
346 148
764 837
22 863
416 906
836 863
784 752
694 346
918 635
963 863
152 863
221 342
473 752
250 635
323 643
102 643
944 833
262 752
185 150
82 342
142 342
383 635
1000 342
30 752
713 837
513 635
12 150
181 346
138 752
661 150
435 342
246 150
387 643
561 635
41 833
797 34...

output:

1 1 2 115 114 118 117 103 102 306 305 396 395 604 603 497 496 810 809 692 691 908 907 695 694 907 906 599 598 906 905 493 492 905 904 492 491 904 903 395 394 903 902 394 393 805 804 393 392 709 709 392 391 709 708 390 389 611 610 389 388 498 497 387 386 402 401 386 385 401 400 298 297 400 399 297 29...

result:

wrong answer 50th numbers differ - expected: '710', found: '709'