QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#558700 | #8012. Jumping Lights | rqoi031 | WA | 0ms | 20496kb | C++20 | 9.2kb | 2024-09-11 17:48:41 | 2024-09-11 17:48:41 |
Judging History
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'