题意

英文版题面

.input-output-copier {
font-size: 1.2rem;
float: right;
color: #888 !important;
cursor: pointer;
border: 1px solid rgb(185, 185, 185);
padding: 3px;
margin: 1px;
line-height: 1.1rem;
text-transform: none;
}

.input-output-copier:hover {
background-color: #def;
}

.test-explanation textarea {
width: 100%;
height: 1.5em;
}

D. Bearish Fanpages
time limit per test

5 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

There is a social website with n fanpages, numbered 1 through n. There are also n companies, and the i-th company owns the i-th fanpage.

Recently, the website created a feature called following. Each fanpage must choose exactly one other fanpage to follow.

The website doesn’t allow a situation where i follows j and at the same time j follows i. Also, a fanpage can't follow itself.

Let’s say that fanpage i follows some other fanpage j0. Also, let’s say that i is followed by k other fanpages j1, j2, ..., jk. Then, when people visit fanpage i they see ads from k + 2 distinct companies: i, j0, j1, ..., jk. Exactly ti people subscribe (like) the i-th fanpage, and each of them will click exactly one add. For each of k + 1 companies j0, j1, ..., jk, exactly people will click their ad. Remaining people will click an ad from company i (the owner of the fanpage).

The total income of the company is equal to the number of people who click ads from this copmany.

Limak and Radewoosh ask you for help. Initially, fanpage i follows fanpage fi. Your task is to handle q queries of three types:

  • 1 i j — fanpage i follows fanpage j from now. It's guaranteed that i didn't follow j just before the query. Note an extra constraint for the number of queries of this type (below, in the Input section).
  • 2 i — print the total income of the i-th company.
  • 3 — print two integers: the smallest income of one company and the biggest income of one company.
Input

The first line of the input contains two integers n and q (3 ≤ n ≤ 100 000, 1 ≤ q ≤ 100 000) — the number of fanpages and the number of queries, respectively.

The second line contains n integers t1, t2, ..., tn (1 ≤ ti ≤ 1012) where ti denotes the number of people subscribing the i-th fanpage.

The third line contains n integers f1, f2, ..., fn (1 ≤ fi ≤ n). Initially, fanpage i follows fanpage fi.

Then, q lines follow. The i-th of them describes the i-th query. The first number in the line is an integer typei (1 ≤ typei ≤ 3) — the type of the query.

There will be at most 50 000 queries of the first type. There will be at least one query of the second or the third type (so, the output won't be empty).

It's guaranteed that at each moment a fanpage doesn't follow itself, and that no two fanpages follow each other.

Output

For each query of the second type print one integer in a separate line - the total income of the given company. For each query of the third type print two integers in a separate line - the minimum and the maximum total income, respectively.

Example
Input
Copy
5 12
10 20 30 40 50
2 3 4 5 2
2 1
2 2
2 3
2 4
2 5
1 4 2
2 1
2 2
2 3
2 4
2 5
3
Output
Copy
10
36
28
40
36
9
57
27
28
29
9 57
Note

In the sample test, there are 5 fanpages. The i-th of them has i·10 subscribers.

On drawings, numbers of subscribers are written in circles. An arrow from A to B means that A follows B.

The left drawing shows the initial situation. The first company gets income from its own fanpage, and gets income from the 2-nd fanpage. So, the total income is 5 + 5 = 10. After the first query ("2 1") you should print 10.

The right drawing shows the situation after a query "1 4 2" (after which fanpage 4 follows fanpage 2). Then, the first company still gets income 5 from its own fanpage, but now it gets only from the 2-nd fanpage. So, the total income is 5 + 4 = 9 now.

阿狸的基环内向树森林

Background

当阿狸醒来的时候,发现自己处在基环内向森林的深处,阿狸渴望离开这个乌烟瘴气的地方。“明天还有与桃子的约会呢”,阿狸一边走一边说,“可是,这个森林的出口在哪儿呢?”

阿狸走啊走,走啊走,就是找不到出口。不知所措的他,突然听到了一个苍老的声音:“这是一片有魔法的密林,这里的树的形态也会时不时的变化,晃晃你的小脑瓜,是不是感觉有水在流动呢?”

Description

阿狸所在的森林有 N 个节点,编号从 1 到 N。每个节点都连出去恰好一条有向边,设 i 号点连出去的点为 A[i]。同时,阿狸发现,A[i]≠i,而且 A[A[i]]≠i。

每个节点上都有一些糖果,第 i 个节点上的糖果数为 B[i]。阿狸定义一个节点的糖果稠密度为 C[i],C[i]求法如下:

假设与 i 距离不超过 1 的点有 D[i]个(包括 i 连出去的点、连向 i 的点以及 i 自己),分别是 P[1]、P[2]…P[D[i]]。

设\(E[i]=\left\lfloor\frac{B[i]}{D[i]}\right\rfloor\),那么\(C[i]=B[i]-D[i]\times E[i]+\sum_{j=1}^{D[i]}E[P[j]]\)

现在阿狸想让你实现一个糖果稠密度分析仪,这个分析仪要支持三种操作:
➢ 1 i j 表示把 A[i]改为 j,保证 j≠i 且 A[j]≠i。
➢ 2 i 表示询问 C[i]的值,即点 i 的糖果稠密度。
➢ 3 表示询问所有节点中最小的 C[i]的值和最大的 C[i]的值。

Input

第一行两个正整数 N 和 Q,表示节点个数和操作个数。
第二行 N 个正整数,第 i 个数表示 B[i]。
第三行 N 个正整数,第 i 个数表示 A[i]。
接下来 Q 行,每行形如 1 i j 或 2 i 或 3 ,表示操作。

Output

有若干行,表示操作 2 和操作 3 的答案。

Sample Input

5 12
10 20 30 40 50
2 3 4 5 2
2 1
2 2
2 3
2 4
2 5
1 4 2
2 1
2 2
2 3
2 4
2 5
3

Sample Output

10
36
28
40
36
9
57
27
28
29
9 57

Data Limitation

对于测试点 1~2,保证 \(N,Q≤5×10^3\),1、2、3 操作出现次数均在 Q/3 左右。
对于测试点 3~6,保证 \(N,Q≤3×10^4\),1、2、3 操作出现次数均在 Q/3 左右。
对于测试点 7~8,保证没有 2 操作,1、3 操作出现次数均在 Q/2 左右。
对于测试点 9~10,保证没有 3 操作,1、2 操作出现次数均在 Q/2 左右。
对于测试点 11~12,保证任何时候 A[i]≤5,1、2、3 操作出现次数均在 Q/3 左右。
对于测试点 13~14,保证任何时候 A[i]≤100,1、2、3 操作出现次数均在 Q/3 左右。
对于测试点 15~16,保证 B[i]≤100,1、2、3 操作出现次数均在 Q/3 左右。
对于 100%的数据,保证 \(3≤N≤10^5,1≤Q≤10^5,1≤B[i]≤10^{12},1≤A[i]≤N\)。

分析

分析那个糖果稠密度,发现可以拆分成“只与i及其周围点数量有关的式子”+“周围一圈的E”。直觉那个修改操作的变动量很少。

由于要修改A,所以想到把“周围一圈的E”拆分成“连向i的点的E”+“i连到的点的E”,然后大力维护即可。

我们可以把一个节点 i 的糖果稠密度 C[i]分成两部分,第一部分是 A[i]对 C[i]的贡献E[A[i]],第二部分是剩下的点对 i 的贡献 C[i]-E[A[i]],设 F[i]=C[i]-E[A[i]]。

对于一个节点 i,我们维护两个信息,一个是 E[i],另一个是所有连向 i 的点的 F 值所构成的集合(也可以用两个堆来维护),设这个集合为 Son[i]。

对于全局我们维护一个集合 S,S 的构成如下:我们把每个节点 i 的 min(Son[i])+E[i]和 max(Son[i])+E[i]两个值加到集合 S 中。

显然,操作 2 的答案就是 E[A[i]]+F[i],而操作 3 的答案就是 min(S)和 max(S)。

考虑操作 1 怎么维护,把 A[i]的值改成了 j,这个操作会影响的节点是 i、j、A[i]、A[j]、A[A[i]]、A[A[j]]、A[A[A[i]]],其中 i 的 A 发生了改变, A[i]和 j 的 D、E、F 和 Son 发生了改变,于是 A[A[i]]和 A[j]的 F 和 Son 也随之改变,于是 A[A[A[i]]]和 A[A[j]]的 Son 也改变了。所以分别对这七个节点维护即可,顺便再维护一下 S,常数超级大。

总复杂度是 O(NlogN)

代码

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;rg char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
    while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std;

co int N=1e5+1;
int n,q,num[N],f[N];
ll t[N],val[N],dev[N],add[N];
multiset<ll> Ans,Son[N];
multiset<ll>::iterator it;
void rev(int x){
    if(Son[x].empty()) return;
    it=Son[x].begin(),Ans.insert(*it+add[x]);
    it=Son[x].end(),--it,Ans.insert(*it+add[x]);
}
void del(int x){
    if(Son[x].empty()) return;
    it=Son[x].begin(),Ans.erase(Ans.find(*it+add[x]));
    it=Son[x].end(),--it,Ans.erase(Ans.find(*it+add[x]));
}
void Rev(int x){
    Son[f[x]].insert(val[x]+dev[x]); // F
}
void Del(int x){
    Son[f[x]].erase(Son[f[x]].find(val[x]+dev[x]));
}
void calc(int x){
    add[x]=t[x]/(num[x]+2); // E
    val[x]=t[x]-(num[x]+1)*add[x]; // left
}
int main(){
//  freopen("forest.in","r",stdin),freopen("forest.out","w",stdout);
    read(n),read(q);
    for(int i=1;i<=n;++i) read(t[i]); // B
    for(int i=1;i<=n;++i) ++num[read(f[i])]; // A,D-2
    for(int i=1;i<=n;++i){
        calc(i);
        dev[f[i]]+=add[i]; // right-E[A]
    }
    for(int i=1;i<=n;++i) Rev(i);
    for(int i=1;i<=n;++i) rev(i);
    for(int i=1,o,x,y;i<=q;++i){
        if(read(o)==1){
            read(x),read(y);
            if(f[x]==y) continue;
            // cut
            del(f[x]),del(f[f[x]]),del(f[f[f[x]]]);
            Del(x),Del(f[x]),Del(f[f[x]]);
            dev[f[x]]-=add[x],--num[f[x]];
            dev[f[f[x]]]-=add[f[x]];
            calc(f[x]);
            dev[f[f[x]]]+=add[f[x]];
            Rev(f[x]),Rev(f[f[x]]);
            rev(f[x]),rev(f[f[x]]),rev(f[f[f[x]]]);
            // link
            f[x]=y;
            del(f[x]),del(f[f[x]]),del(f[f[f[x]]]);
            Del(f[x]),Del(f[f[x]]);
            dev[f[x]]+=add[x],++num[f[x]];
            dev[f[f[x]]]-=add[f[x]];
            calc(f[x]);
            dev[f[f[x]]]+=add[f[x]];
            Rev(x),Rev(f[x]),Rev(f[f[x]]);
            rev(f[x]),rev(f[f[x]]),rev(f[f[f[x]]]);
        }
        else if(o==2){
            read(x);
            printf("%lld\n",dev[x]+val[x]+add[f[x]]);
        }
        else{
            it=Ans.begin(),printf("%lld ",*it);
            it=Ans.end(),--it,printf("%lld\n",*it);
        }
    }
    return 0;
}

CF643D Bearish Fanpages的更多相关文章

  1. An Introduction to Stock Market Data Analysis with R (Part 1)

    Around September of 2016 I wrote two articles on using Python for accessing, visualizing, and evalua ...

  2. B

    baababblebabblerbabebabelbaboonbabybabyhoodBabylonBabylonianbacchanalbacchanalianbachelorbacillusbac ...

  3. 用Python做股市数据分析(二)

    本文由 伯乐在线 - 小米云豆粥 翻译.未经许可,禁止转载!英文出处:Curtis Miller.欢迎加入翻译组. 这篇博文是用Python分析股市数据系列两部中的第二部,内容基于我在犹他大学 数学3 ...

  4. [转]Introduction to Learning to Trade with Reinforcement Learning

    Introduction to Learning to Trade with Reinforcement Learning http://www.wildml.com/2018/02/introduc ...

  5. IOTA price analysis

    Iota coinchart Look at the trendline drawn in red color, at the very first beginning of this month, ...

  6. Introduction to Learning to Trade with Reinforcement Learning

    http://www.wildml.com/2015/12/implementing-a-cnn-for-text-classification-in-tensorflow/ The academic ...

  7. 【转】用Python做股市量化策略投资数据分析

    金融量化分析介绍     本文摘要; 金融量化分析介绍 1.什么是金融量化分析 2.金融量化分析可以干什么 3.为什么将python运用于金融 4.常用库简介 1.什么是金融量化分析 从标题中我们可以 ...

  8. 退役III次后做题记录(扯淡)

    退役III次后做题记录(扯淡) CF607E Cross Sum 计算几何屎题 直接二分一下,算出每条线的位置然后算 注意相对位置这个不能先搞出坐标,直接算角度就行了,不然会卡精度/px flag:计 ...

  9. ta-lib 里的蜡烛图形态函数源码

    ta-lib 里的蜡烛图形态函数源码 以CDL2CROWS为例, 看一看c语言的源码: 有关的源码文件包括 d:\Documents\Pictures\ta-lib\c\src\ta_func\ta_ ...

随机推荐

  1. javascript 跑马灯

    1.看了写跑马灯的教程案例,隔了段时间自己写了一个简单的跑马灯.将过程中遇到的问题特此记录下来 代码如下: <!DOCTYPE html> <html> <head> ...

  2. 回溯算法 LEETCODE别人的小结 一八皇后问题

    回溯算法实际上是一个类似枚举的搜索尝试过程,主要是在搜索尝试中寻找问题的解,当发现已不满足求解条件时,就回溯返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目的.但是当探索到某 ...

  3. Mysql InnoDB三大特性-- 自适应hash index

    Mysql InnoDB三大特性-- 自适应hash index

  4. 读书笔记 enum枚举之位标志属性(Flags)浅析

    针对enum枚举来说,可以定义位标志属性,从而使该枚举类型的实例可以存储枚举列表中定义值的任意组合.可以用 与(&).或(|).异或(^)进行相应的运算.废话不多说,代码最直接. //每一个定 ...

  5. html页面技巧

    Query获取Select选择的Text和Value: 语法解释: 1. $("#select_id").change(function(){//code...});   //为S ...

  6. 实力封装:Unity打包AssetBundle(番外篇)

    前情提要:第二种打包方式. 自定义AssetBundle包扩展名 在之前的教程中,我们已经多次提到过扩展名了,并且也已经说明了如何设置自定义的AssetBundle扩展名.至于为什么还要把它单独拿出来 ...

  7. MySQL:数据表基本操作

    数据表基本操作 注意点: 1.数据表中已经有数据时,轻易修改数据类型,有可能因为不同的数据类型的数据在机器 中存储的方式及长度并不相同,修改数据类型可能会影响到数据表中已有的数据类型. 2.  数据表 ...

  8. Vue 项目架构设计与工程化实践

    来源 文中会讲述我从0~1搭建一个前后端分离的vue项目详细过程 Feature: 一套很实用的架构设计 通过 cli 工具生成新项目 通过 cli 工具初始化配置文件 编译源码与自动上传CDN Mo ...

  9. Linux运维命令总结(-)

    Linux运维命令总结(-)  此次整理linux运维常用命令13个,常用linux运维命令大概有150个,约占百分之十,大牛见笑,本人菜鸟一枚不才整理如下,如有不正确之处,请多多指正. 1.创建目录 ...

  10. excel单元格内容连接

    1.连接符号: & 举例子:C1= A1&B1 2.生成sql: CONCATENATE("(seq_table.nextval,sysdate, 'test',sysdat ...