怎么说?发现自己越来越菜了 到了不写题解写不出来题目的地步了。。

这次题目我都有认真思考 尽管思考的时候状态不太好 但是 我想 再多给我时间也思考不出来什么吧

所以写一份题解。

T1 n个点的有根树 1号点为根 第i个点的点权为\(w_i\) \(1\leq w_i\leq L\) 定义一个长度为L的序列是完美的 当且仅当\(\forall 1\leq i\leq L\)

都有\(w_{a_i}=i\)且\(\forall 1\leq k<i\) \(a_k\)为\(a_i\)的父亲。定义\(f_i\)为第i个点的父亲.

有m次修改 对于第i次修改会把\(u=(i-1)%mod+n+1\)的点权修改为\(v_i\)

对于每次修改过后的答案乘上i 对1e9+7取模 询问m次修改的答案和。\(L\leq n\leq 1e6\) \(m\leq 2e6\) \(1\leq f_i<i\)

显然有一个nm的dp 只不过放到了树上。

不难发现这个L很像我们的最长上升子序列 如果该序列中存在最长上升子序列的话 那这样求的就是最长上升子序列的方案数了。

不过每次有单点修改。往这个方向思考 是无果的 基本上我们最长上升子序列方案数不支持修改 查询。

但是可以发现 每次修改的点是有序的 1 2 3 4 5...n...1.... 同时看题目中关键的条件 \(f_i<i\)自己的父亲小于自己 也就是说对于每个点在修改的时候 自己的父亲已经被改过了 这是这道题的关键之处 修改并非无序修改。

做题的时候抓住题目中的条件来解决问题 把题目中的条件都理解透了 再思考 问题的解决。

考虑对于链的怎么做 其实就是序列了 容易设出设\(f_i\)表示以i为结尾的方案数 \(g_i\)表示以i为开头的方案数。

一个点将会被修改掉 我们需要-其在原本的答案中所占方案数+新产生的方案。

所占方案 那显然是\(f_i\cdot g_i\) 考虑一个新的数字\(v_i\) 其产生的方案为 \((\sum\limits_{1\leq k<i,w_k=v_i-1}f_k)\cdot (\sum\limits_{i+1\leq k\leq L,w_k==v_i+1}g_k)\)

可以发现这正是我们新的f值 和g值的相乘。

但是不可做的一点是 由于存在修改 我们一个点的f 和g容易得出 但是其他点的f和g的值将会被扰乱导致下一个点再这样做的时候结果不正确。

当然这种修改是很难维护的 尽管我们维护值域线段树 想做出这样的修改也很不容易。

接下来利用题目中的条件 自己的父亲比自己先修改这一条件。

可以发现我们当前点在修改过后 对于新的f值我们利用父亲修改过后的再累计一个方案数维护。

对于g的维护可以发现还是旧的就行 因为儿子不可能发生修改。

但是有多次轮回修改怎么解决。其实可以直接莽了 每次树形dp处理一轮的问题。时间复杂度O(n) 同时也处理O(n)个问题。

那么有O(m)个问题 显然 我们时间复杂度就是O(m)的 简单来讲就是 m/n轮处理 每次时间复杂度O(n)故总时间复杂度O(m).

考虑在树上怎么做我们还是套用刚才的模型来做 对于f显然可以这样做。

考虑g的维护 发现处理完一个子树的g 这个子树的g由于对我们的父亲还有贡献我们不能将其清理掉 所以可以进行桶差分一下即可 超级好写。

综上我们解决了这个问题 时间复杂度O(m).(真的不是什么LIS的方案数啊啊啊。

可以发现当自己认为问题不可被解决时 80%是自己没有认真读题。

···

int n,m,L,len,top;

int a[MAXN],v[MAXN];ll cf[MAXN],w[MAXN],b[MAXN],g[MAXN],cg[MAXN],f[MAXN],cnt,ans;

int lin[MAXN],ver[MAXN],nex[MAXN];

inline void add(int x,int y)

{

ver[++len]=y;

nex[len]=lin[x];

lin[x]=len;

}

inline void dp(int x)

{

ll ww=cg[v[x]+1];

ll w1=cg[a[x]+1];

//求出f数组 f数组表示以某个点为结尾的方案数 更新过的v数组来求出

f[x]=cf[v[x]-1];

if(v[x]1)f[x]=1;

w[x]=cf[a[x]-1];

if(a[x]1)w[x]=1;

cf[v[x]]=(cf[v[x]]+f[x])%mod;

go(x)dp(tn);

cf[v[x]]=(cf[v[x]]-f[x])%mod;

//求出g数组 g数组表示以某个点为开头的方案数 通过a数组求出

g[x]=(cg[v[x]+1]-ww)%mod;

if(v[x]L)g[x]=1;

b[x]=(cg[a[x]+1]-w1)%mod;

if(a[x]L)b[x]=1;

cg[a[x]]=(cg[a[x]]+b[x])%mod;

if(a[x]1)ans=(ans+b[x])%mod;

}

int main()

{

freopen("1.in","r",stdin);

//freopen("tree.out","w",stdout);

get(n);get(m);get(L);

rep(2,n,i)add(read(),i);

rep(1,n,i)v[i]=get(a[i]);

int st;

rep(1,m,i)

{

int x=(i-1)%n+1;

if(x1)st=i;

a[x]=v[x];

get(v[x]);

if(xn||im)

{

rep(1,n,j)cg[j]=cf[j]=0;

rep(x+1,n,j)a[j]=v[j];

ans=0;dp(1);

rep(1,x,j)

{

ans=(ans-w[j]b[j]+f[j]g[j])%mod;

cnt=(cnt+ans*st)%mod;++st;

}

}

}

printf("%lld\n",(cnt+mod)%mod);

return 0;

}

可以说这道题并非很难 失误之处在于没有抓住题目种给的条件。

省选模拟赛day4的更多相关文章

  1. FCS省选模拟赛 Day4

    传送门 Solution Code  /* 斯坦纳树:O(n*3^n+kE*2^n) 暂且把O(k*E)当成是spfa的复杂度 15:15~16:20 原题:bzoj_4774 */ #include ...

  2. 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解

    今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...

  3. @省选模拟赛03/16 - T3@ 超级树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...

  4. 3.28 省选模拟赛 染色 LCT+线段树

    发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...

  5. 省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)

    一 稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数 一个挺trick的想法是: 由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和 那么如果把不存在于原树中的 ...

  6. NOI2019省选模拟赛 第五场

    爆炸了QAQ 传送门 \(A\) \(Mas\)的童年 这题我怎么感觉好像做过--我记得那个时候还因为没有取\(min\)结果\(100\to 0\)-- 因为是个异或我们肯定得按位考虑贡献了 把\( ...

  7. NOI2019省选模拟赛 第六场

    传送门 又炸了-- \(A\) 唐时月夜 不知道改了什么东西之后就\(A\)掉了\(.jpg\) 首先,题目保证"如果一片子水域曾经被操作过,那么在之后的施法中,这片子水域也一定会被操作&q ...

  8. 省选模拟赛 arg

    1 arg (arg.cpp/in/out, 1s, 512MB)1.1 Description给出一个长度为 m 的序列 A, 请你求出有多少种 1...n 的排列, 满足 A 是它的一个 LIS. ...

  9. 5.10 省选模拟赛 拍卖 博弈 dp

    LINK:拍卖 比赛的时候 前面时间浪费的有点多 写这道题的时候 没剩多少时间了. 随便设了一个状态 就开始做了. 果然需要认真的思考.其实 从我的状态的状态转移中可以看出所有的结论. 这里 就不再赘 ...

随机推荐

  1. tidyverse|数据分析常规操作-分组汇总(sumamrise+group_by)

    | 本文首发于 “生信补给站” https://mp.weixin.qq.com/s/tQt0ezYJj3H7x3aWZmKVEQ 使用tidyverse进行简单的数据处理: 盘一盘Tidyverse ...

  2. 阿里云服务器ecs配置之安装jdk(转)

    一.安装环境 操作系统:Centos 7.4 JDK版本:1.8 工具:Xshell5.Xftp5 二.安装步骤 第一步:下载安装包 (官网)链接: 下载适合自己系统的jdk版本,如图:我下载的是64 ...

  3. day05 垃圾回收机制(超小白讲解)

    垃圾回收机制 在学习这个抽象概念前,老习惯,灵魂二问 什么是?为什么要有? 引言:在程序运行到变量定义时,会在内存空间中存放变量值,然而内存空间是有限的,变量是无限的. Q:如何在有限的内存里存里存放 ...

  4. 题解:2018级算法第六次上机 C6-不Nan的过河

    题目描述: 样例: 实现解释: 一道因为没排序做了一个小时没做出来的二分答案模板题(手动呲牙) 知识点: 二分答案,最大值最小化 坑点: 排序,judge(mid)函数内计数的实现 其实从最长一步的最 ...

  5. Python and or not 优先级

    not > and >or 1 or 5 and 4: -> 1 or 4-> 1 (1 or 5) and 4: ->1 and 4 ->4 x or y . x ...

  6. (三)学习了解OrchardCore笔记——灵魂中间件ModularTenantContainerMiddleware的第一行①的模块部分

    了解到了OrchardCore主要由两个中间件(ModularTenantContainerMiddleware和ModularTenantRouterMiddleware)构成,下面开始了解Modu ...

  7. python 读取指定文件夹中的指定文件类型的文件名

    import numpy as np import os path = 'F:\\wenjian'#指定文件所在路径 filetype ='.csv'#指定文件类型 def get_filename( ...

  8. java 面向对象(二十四):interface:接口

    interface:接口1.使用说明: 1.接口使用interface来定义 * 2.Java中,接口和类是并列的两个结构 * 3.如何定义接口:定义接口中的成员 * * 3.1 JDK7及以前:只能 ...

  9. 机器学习实战基础(二十三):sklearn中的降维算法PCA和SVD(四) PCA与SVD 之 PCA中的SVD

    PCA中的SVD 1 PCA中的SVD哪里来? 细心的小伙伴可能注意到了,svd_solver是奇异值分解器的意思,为什么PCA算法下面会有有关奇异值分解的参数?不是两种算法么?我们之前曾经提到过,P ...

  10. Python并发编程04 /多线程、生产消费者模型、线程进程对比、线程的方法、线程join、守护线程、线程互斥锁

    Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线程join.守护线程.线程互斥锁 目录 Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线 ...