打满暴力好像是一种挑战,已经连续几天考试最后一个小时自闭了,因为自以为打完了暴力,然而,结果往往差强人意
大概是考试的策略有些问题
T1:
待填
T2:
考虑到,一开始的形如$x_i+x_fa=w$形成一棵以1为根节点的树,也就是说任意的点都可以用$x_1$表示
设1为偶数点,那么奇数点都可以表示成形如$k-x_i$的形式,偶数点都可以表示为形如$k+x_1$的形式
考虑操作1:我们假设已知$x_u,x_v$用$x_i$的表示和$u,v$是奇数点还是偶数点,分以下情况讨论
1.两个都是奇数点,那么有$k_u-x_1+k_v-x_1=s$,移项得到$2x_1=s+k_u+k_v$,计算答案就好
2.两个都是偶数点,那么有$k_u+x_1+k_v+x_1=s$,移项得到$2x_1=s-k_u-k_v$,计算答案就好
3.一个是奇数点,一个是偶数点,这样的话$x_1$就会消掉,判断得到的结果与给定的s是否相同即可
显然初始化一遍dfs每个点的表示和奇偶都可以轻易得到
考虑操作2如何维护?
我们发现改变一个点与其父亲的$w$值最终改变表达的只是这个点子树里的点,我们把奇数点和偶数点分情况讨论,用树状数组维护区间加就好
如当前点已知表达为$x$,接下来的表达分别为$w_1-x,w_2-w_1+x,w_3-w_2+w_1-x$
总结起来就是奇到奇是+,偶到偶是+,奇到偶和偶到奇都是-(这个主要是方便笔者自己理解...可能有点抽象,感性理解一下)
std用了很神奇的一个树状数组同时解决了奇点和偶点的修改,用的就是上述的性质
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int N=1e6+15; int n,q,tot,tim; int head[N],dep[N],dfn[N],edfn[N],t[N],w[N]; struct EDGE { int to,nxt,ww; }edge[N]; inline int read() { char ch=getchar(); int s=0,f=1; while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();} return s*f; } void ad(int u,int v,int ww) { edge[++tot]=(EDGE){v,head[u],ww}; head[u]=tot; } void dfs(int x) { dfn[x]=++tim; for (int i=head[x];i;i=edge[i].nxt) { int y=edge[i].to; dep[y]=dep[x]^1; dfs(y); } edfn[x]=tim; } void add(int x,int y) { while (x<=n) { t[x]+=y; x+=x&-x; } } int sum(int x) { int re=0; while (x) { re+=t[x]; x-=x&-x; } return re; } int main() { // freopen("equation.in","r",stdin); // freopen("equation.out","w",stdout); n=read();q=read(); for (int i=2,u;i<=n;i++) { u=read();w[i]=read(); ad(u,i,w[i]); } dfs(1); for (int i=2;i<=n;i++) if (!dep[i]) w[i]=-w[i]; for (int i=2;i<=n;i++) {add(dfn[i],w[i]);add(edfn[i]+1,-w[i]);} while (q--) { int opt=read(); if (opt==1) { int u=read(),v=read(),s=read(); int x=sum(dfn[u]),y=sum(dfn[v]); if (dep[u]&&dep[v]) { ll rt=1ll*x+y-s; if (rt%2!=0) puts("none"); else printf("%lld\n",rt/2); } else if (!dep[u]&&!dep[v]) { ll rt=1ll*x+y+s; if (rt%2!=0) puts("none"); else printf("%lld\n",rt/2); } else { if (!dep[u]) swap(u,v),swap(x,y); if (x-y==s) puts("inf"); else puts("none"); } } if (opt==2) { int u=read(),ww=read(); if (!dep[u]) ww=-ww; add(dfn[u],ww-w[u]);add(edfn[u]+1,w[u]-ww); w[u]=ww; } } return 0; }
T3:
待填