1 条题解
-
0
是这样的,在 中,先看T1,贪心秒了(就是这次 2024年第二届科技节信息竞赛 的T2 吧)。
然后开 T2,这不就物理题吗,打了差不多半个小时打出来了,然后测大样例,然后发现全对。
这时候我突然发现自己一个细节不对,进入 2 阶段,调试。结果改成当时认为的正确方法时,发现倒数第二个大样例错了,崩溃,调代码,调了好长时间没调出来,先做 T3。
当时 T3 但凡做的时间久一点就做出来了,是一个简单的 dp,但是当时只打了个 20 分的暴力。
然后又回去调 T2,到最后都没调出来,出来后以为自己只有 160 分了,直接 emo 了。所以说心情异常低落。(其实当时是把 -1 写成 0 了。但是最后 CCF 数据过水没把我卡掉(喜)。
晚上打 cf,结果同机房大佬加了 354 分,我只加了 35 分,我还是菜啊。
对了,忘记说题解了。挺裸一题,感觉没啥好写的。
我在题目最后一行藏了个东西:对于 的测试点,保证 ,所以是一个树,那么在树上的操作就很简单了。
线段树 + 树链剖分秒了。
其实代码不是很长,主要是我的习惯硬生生把 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; }
禁止抄代码
- 1
信息
- ID
- 961
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 1
- 标签
- 递交数
- 4
- 已通过
- 1
- 上传者