Equation

题目描述

有一棵\(n\)个点的以\(1\)为根的树,以及\(n\)个整数变量\(x_i\)。树上\(i\)的父亲是\(f_i\),每条边\((i,f_i)\)有一个权值\(w_i\),表示一个方程\(x_i+x_{f_i}=w_i\),这\(n-1\)个方程构成了一个方程组。

现在给出\(q\)个操作,有两种类型:

•\(1\ u\ v\ s\),表示询问加上\(x_u+x_v=s\)这个方程后,整个方程组的解的情况。具体来说,如果方程有唯一解,输出此时\(x_1\)的值;如果有无限多个解,输出inf;如果无解,输出none. 注意每个询问是独立的.

•\(2\ u\ w\),表示将\(w_u\)修改为\(w\).

输入输出格式

输入格式

从文件equation.in中读入数据.

第一行两个整数\(n,q\)。

接下来\(n-1\)行,第\(i\)行有两个整数\(f_{i+1}\)和\(w_{i+1}\)。

接下来\(q\)行,每行表示一个操作,格式见问题描述。

输出格式

输出到文件equation.out中.

对于每个询问输出一行表示答案.

说明

对于所有数据,有\(1\le n,q\le 10^6,1\le f_i\le i -1,1\le u,v\le n; -10^3\le w,w_i\le 10^3,-10^9\le s\le 10^9\).

• \(\text{Subtask1}(3\%),n\le 10,q=0\).

• \(\text{Subtask2}(18\%), n=2\).

• \(\text{Subtask3}(32\%), n,q\le 10^3\).

• \(\text{Subtask4}(33\%), n,q\le 10^5\).

• \(\text{Subtask5}(14\%)\),没有特殊的约束.


给个1e5,给个1e6真的坑。

1e6就认为是\(O(n)\)做法好吗(反正我大常数这辈子过不了1e6的\(nlogn\)了

不过为了卡两个\(log\)的还可以理解了


发现连上一条边后,把路径的边权正负相加可以消去很多项。

当路径长度为奇数,判断无解or多解

偶数,解出来判断是否有整数解

然后求上去就行了

发现我们要维护路径求和和单点修改

可以无脑树剖但是不能拿满分

路径求和可以根据lca分成两个分别求

维护一个到根节点的路径长度

跑一下dfs序,就变成了维护区间求和和单点加,树状数组就可以了

然而我常数真的大。。

细节处理起来听麻烦的


Code:

#include <cstdio>
#define ll long long
const int N=1e6+10;
int read()
{
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9') {if(c=='-') f=-f;c=getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*f;
}
int n,q;
int head[N],to[N],Next[N],cnt;
void add(int u,int v)
{
to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
}
int dep[N],f[N][21],w[N],dfn[N],siz[N],dfsclock,tmp;
ll s[N];
void swap(int &x,int &y){tmp=x,x=y,y=tmp;}
void modify(int x,ll de)
{
for(int i=x;i<=n;i+=i&-i)
s[i]+=de;
}
ll query(int x)
{
ll sum=0;
for(int i=x;i;i-=i&-i)
sum+=s[i];
return sum;
}
void dfs(int now)
{
dfn[now]=++dfsclock,siz[now]=1;
modify(dfn[now],w[now]*(dep[now]&1?1:-1));
for(int i=1;f[now][i-1];i++) f[now][i]=f[f[now][i-1]][i-1];
for(int i=head[now];i;i=Next[i])
dep[to[i]]=dep[now]+1,dfs(to[i]),siz[now]+=siz[to[i]];
modify(dfn[now]+siz[now],w[now]*(dep[now]&1?-1:1));
}
int LCA(int u,int v)
{
for(int i=20;~i;i--)
if(dep[f[u][i]]>=dep[v])
u=f[u][i];
if(u==v) return u;
for(int i=20;~i;i--)
if(f[u][i]!=f[v][i])
u=f[u][i],v=f[v][i];
return f[u][0];
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
n=read(),q=read();
for(int i=2;i<=n;i++)
f[i][0]=read(),w[i]=read(),add(f[i][0],i);
dfs(1);
for(int p,op,u,v,s,i=1;i<=q;i++)
{
op=read();
if(op==1)
{
u=read(),v=read(),s=read();
if(dep[u]<dep[v]) swap(u,v);
int lca=LCA(u,v);p=u;
if(dep[u]-dep[v]&1)
{
ll k=(query(dfn[u])-query(dfn[lca]))*(dep[u]&1?1:-1);
k+=(query(dfn[v])-query(dfn[lca]))*(dep[v]&1?1:-1);
if(s==k) printf("inf\n");
else printf("none\n");
}
else
{
ll k=1ll*(query(dfn[u])-query(dfn[lca]))*(dep[u]&1?1:-1);
k+=1ll*(query(dfn[v])-query(dfn[lca]))*(dep[v]&1?-1:1);
k=k+s;
if(k&1) printf("none\n");
else
{
k>>=1;
printf("%lld\n",query(dfn[p])-k*(dep[p]&1?1:-1));
}
}
}
else
{
u=read();
p=read();
modify(dfn[u],(p-w[u])*(dep[u]&1?1:-1));
modify(dfn[u]+siz[u],(w[u]-p)*(dep[u]&1?1:-1));
w[u]=p;
}
}
return 0;
}

2018.10.6

雅礼集训 Day6 T2 Equation 解题报告的更多相关文章

  1. 雅礼集训 Day7 T1 Equation 解题报告

    Reverse 题目背景 小\(\text{G}\)有一个长度为\(n\)的\(01\)串\(T\),其中只有\(T_S=1\),其余位置都是\(0\).现在小\(\text{G}\)可以进行若干次以 ...

  2. 雅礼集训 Day6 T1 Merchant 解题报告

    Merchant 题目描述 有\(n\)个物品,第\(i\)个物品有两个属性\(k_i,b_i\),表示它在时刻\(x\)的价值为\(k_i\times x+b_i\). 当前处于时刻\(0\),你可 ...

  3. 雅礼集训 Day3 T2 u 解题报告

    u 题目背景 \(\frac 14\) 遇到了一道水题,完全不会做,于是去请教小\(\text{D}\).小\(\text{D}\)看了一眼就切掉了这题,嘲讽了\(\frac 14\)一番就离开了. ...

  4. 雅礼集训 Day3 T2 v 解题报告

    v 题目背景 \(\frac 14\)遇到了一道水题,又完全不会做,于是去请教小\(\text{D}\).小\(\text{D}\)看了\(0.607\)眼就切掉了这题,嘲讽了\(\frac 14\) ...

  5. 「雅礼集训 2017 Day2」解题报告

    「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...

  6. 「雅礼集训 2017 Day1」 解题报告

    「雅礼集训 2017 Day1」市场 挺神仙的一题.涉及区间加.区间除.区间最小值和区间和.虽然标算就是暴力,但是复杂度是有保证的. 我们知道如果线段树上的一个结点,\(max=min\) 或者 \( ...

  7. 雅礼集训 Day3 T3 w 解题报告

    w 题目背景 \(\frac 14\)遇到了一道水题,双完全不会做,于是去请教小\(\text{D}\).小\(\text{D}\)看了\(0.607^2\)眼就切掉了这题,嘲讽了\(\frac 14 ...

  8. 雅礼集训 Day1 T3 画作 解题报告

    画作 题目描述 小\(\mathrm{G}\)的喜欢作画,尤其喜欢仅使用黑白两色作画. 画作可以抽象成一个\(r\times c\)大小的\(01\)矩阵.现在小\(\mathrm{G}\)构思好了他 ...

  9. 雅礼集训 Day5 T3 题 解题报告

    题 题目背景 由于出题人赶时间所以没办法编故事来作为背景. 题目描述 一开始有\(n\)个苹果,\(m\)个人依次来吃苹果,第\(i\)个人会尝试吃\(u_i\)或\(v_i\)号苹果,具体来说分三种 ...

随机推荐

  1. JS里访问纯数字ID对象时出现问题

    <p id="1">Hello</p> 例如上面的例子,id为纯数字会出错.此时用js去获取该对象会报错,查找不到该对象. 原因:必须是字母开头,或是下划线 ...

  2. 洛谷P1762 偶数(找规律)

    题目描述 给定一个正整数n,请输出杨辉三角形前n行的偶数个数对1000003取模后的结果. 输入输出格式 输入格式: 一个数 输出格式: 结果 输入输出样例 输入样例#1: 复制 6 输出样例#1:  ...

  3. nginx虚拟主机搭建

    nginx [engine x]是 Igor Sysoev 编写的一个 HTTP 和反向代理服务器,另外它也可以 作为邮件代理服务器. 它已经在众多流量很大的俄罗斯网站上使用了很长时间,这些网站包括 ...

  4. python之获取微信好友列表并保存文档中

    代码如下 from wxpy import * from pprint import pprint #登录微信 bot = Bot() my_friend = bot.friends() f = op ...

  5. linux socketpair

    相对于无名管道来说,socketpair也是使用在亲缘进程之间,不过它提供了能够全双工通信的通道 man socketpair: #include <sys/types.h> /* See ...

  6. https://www.cnblogs.com/gaoxiang12/p/3695962.html

    https://www.cnblogs.com/gaoxiang12/p/3695962.html

  7. POJ:3279-Fliptile(矩阵反转)

    Fliptile Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14701 Accepted: 5381 Description ...

  8. 17-比赛1 D - IPC Trainers (贪心 + 优先队列)

    题目描述 本次印度编程训练营(Indian Programming Camp,IPC)共请到了 N 名教练.训练营的日程安排有 M 天,每天最多上一节课.第 i 名教练在第 Di 天到达,直到训练营结 ...

  9. scrapy进行分布式爬虫

    今天,参照崔庆才老师的爬虫实战课程,实践了一下分布式爬虫,并没有之前想象的那么神秘,其实非常的简单,相信你看过这篇文章后,不出一小时,便可以动手完成一个分布式爬虫! 1.分布式爬虫原理 首先我们来看一 ...

  10. impala presto SparkSql性能测试对比

      目标是为测试impala presto SparkSql谁的性能更佳,以下结果底层查询的都是普通textfile snappy压缩后数据,规模为15台机器,若以orcfile.parquet速度能 ...