Equation
调了半个下午啊。
基本上所有人都是正解;
自闭了。
考场上想出来了同一条链上的点互相间都可以有方程。
但是不自信能想出正解。
就想高斯消元,结果挂了。
正解是根据我刚刚说的那个性质,可以发现1与所有点都共链,那么所有未知数都可以用1的变量来表示。
得到额外的方程后,先看方程里的未知数用\(x_1\)表示的形式加和是不是给出的数,若是,那么此时\(x_1\)被消掉,只有\(n-1\)个有效方程,是无穷解,若不相同,就是无解。
若一消不掉,就可以解出了。
但有个细节,题中说所有未知数是整数,就意味着若解是实型,也算无解。
至于说修改,其实当所有未知量用1表示时都有另外一个加数\(b\),是可以求的,有规律,懒得写了,很好推。
对于这个\(b\)可以做差分树状数组。
以\(DFS\)序为下表建立数组。
奇数偶数要分开考虑,因为奇偶性不同,同一个数的系数正负不同,区间修改时加的数就不同。
Code
#include<bits/stdc++.h>
using namespace std;
namespace STD
{
#define rr register
typedef long long ll;
const int N=1e6+4;
int n,q;
int to[N],dire[N],head[N],fa[N];
int size[N],depth[N],w[N];
int id[N],reid[N],w_[N];
inline void add(int f,int t)
{
static int num=0;
to[++num]=t;
dire[num]=head[f];
head[f]=num;
}
int read()
{
rr int x_read=0,y_read=1;
rr char c_read=getchar();
while(c_read<'0'||c_read>'9')
{
if(c_read=='-') y_read=-1;
c_read=getchar();
}
while(c_read<='9'&&c_read>='0')
{
x_read=(x_read<<3)+(x_read<<1)+(c_read^48);
c_read=getchar();
}
return x_read*y_read;
}
class tree_a
{
private:
ll a[N];
inline int lowbit(int x){return x&(-x);}
public:
void insert(int,int);
ll query(int,int);
}t[2];
void tree_a::insert(int pos,int val)
{
while(pos<=n)
{
a[pos]+=val;
pos+=lowbit(pos);
}
}
ll tree_a::query(int l,int r)
{
ll sum=0;
while(r)
{
sum+=a[r];
r-=lowbit(r);
}
while(l)
{
sum-=a[l];
l-=lowbit(l);
}
return sum;
}
void dfs(int x)
{
static int num=0;
size[x]=1;
id[x]=++num;
reid[num]=x;
for(rr int i=head[x];i;i=dire[i])
{
depth[to[i]]=depth[x]+1;
w[to[i]]-=w[x];
dfs(to[i]);
size[x]+=size[to[i]];
}
}
};
using namespace STD;
int main()
{
n=read(),q=read();
for(rr int i=2;i<=n;i++)
{
fa[i]=read();
w_[i]=w[i]=read();
add(fa[i],i);
}
dfs(1);
for(rr int i=1;i<=n;i++)
{
t[depth[i]&1].insert(id[i],w[i]-w[reid[id[i]-1]]);
t[(depth[i]&1)^1].insert(id[i],w[i]-w[reid[id[i]-1]]);
}
while(q--)
{
int opt=read();
if(opt==1)
{
int u=read(),v=read(),s=read();
int a1=(depth[u]&1)?-1:1;
int a2=(depth[v]&1)?-1:1;
ll b1=0,b2=0;
b1=t[depth[u]&1].query(0,id[u]);
b2=t[depth[v]&1].query(0,id[v]);
if(a1!=a2)
{
if(b1+b2==s) printf("inf\n");
else printf("none\n");
}
else
{
a1+=a2;
b1+=b2;
if((s-b1)%a1) printf("none\n");
else printf("%lld\n",(s-b1)/a1);
}
}
else
{
int u=read(),v=read();
int u_=u;
t[depth[u_]&1].insert(id[u_],v-w_[u_]);
t[(depth[u_]&1)^1].insert(id[u_],w_[u_]-v);
t[depth[u_]&1].insert(id[u_]+size[u_],w_[u_]-v);
t[(depth[u_]&1)^1].insert(id[u_]+size[u_],v-w_[u_]);
w_[u_]=v;
}
}
}
2021-08-09 20:47:16 星期一