先来整理题目

T1题目大意:给出n个数字和一个质数作为模数,一个变量x初始值为1。进行m次操作,每次让x随机乘上n个数中的一个,问m次操作以后x的期望值。

答案一定可以用分数表示,输出分子乘分母逆元的值。

数学一直不好,期望这块更是似懂非懂。上来看了一眼数据范围和测试点提示,写了两行骗分走了。

其实这个骗分我没看全也没理解对,阴差阳错碰对了一个点。正解是原根把矩阵乘法转化成加法,循环矩阵快速幂。【当然没有搞懂,之后去翻别人的博客学习】

留个坑。

T2题目大意:给出一棵边权为1的树,每个点有一个权值记作a[i]。对于一个点,其他每个点到这个点的距离乘上那个点的a[i]再求和,记作这个点的重要程度b[i]。

给出全部点的a[i]或者全部点的b[i],求出没给出的a[i]或b[i]。

对于给出a[i]求b[i]:一眼换根DP,切了。

然后出分一看快乐爆零。后来研究研究代码,换根的式子推错了。【后来改的时候又错了一次】

对于给出b[i]求a[i]:一眼高斯消元,但是其实我没写过高斯消元,折腾了半天放弃调试滚去T3了。

后来了解到求a[i]正解不是高斯消元。考虑每两个相邻b[i],b[j]之间的差别,会发现以它们为分界,对于b[i]一边的点贡献多1,对于b[j]另一边的点贡献多1。

尝试用b[i]减去它父亲的b[fa[i]]。先看b[i]为根的子树的a[i]之和siz[i],siz[i]对于b[i]的贡献比对于b[fa[i]]的贡献少1。而看全部a[i]之和sum扣去siz[i]的这一部分,对于b[i]的贡献比对于b[fa[i]]的贡献多1。那么b[i]-b[fa[i]]=-siz[i]+(sum-siz[i])=sum-2*siz[i]。

这样能够对于每一个非根节点列出n-1个式子。那么对于我们选定的根节点【这里设为1】,发现b[1]=siz[2]+siz[3]+siz[4]+...+siz[n]。b[1]中有2-n所有的siz[i],而之前我们列出的n-1个式子里面各有一个siz[i]。

那么把所有b[i]-b[fa[i]]加起来,再加上b[1]*2,就是全部a[i]之和sum。

得到sum以后我们可以考虑从根一路跑到叶节点,把sum代入回式子能得到每一个siz[i],发现叶节点的siz[i]就是a[i]。然后向上处理,用当前节点的siz减去儿子的siz,最后得到的就是a。对于根节点,它没有siz,但是sum1减去所有的siz就是a[1],也可以在同一个dfs里面特判一下解决。

代码:

#include<iostream>
#include<cstdio>
using namespace std;
int t,n,opt;
int ver[],Next[],head[],tot;
int a[];
long long sum[],siz[],sum1,b[];
void add(int x,int y){
ver[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
void dfs(int x,int fa){
siz[x]=a[x];
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y==fa)continue;
dfs(y,x);
siz[x]+=siz[y];
sum[x]+=sum[y]+siz[y];
}
}
void dfs1(int x,int fa){
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y==fa)continue;
sum[y]=sum[x]+sum1-*siz[y];
dfs1(y,x);
}
}
void dfs2(int x,int fa){
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y==fa)continue;
sum1+=b[y]-b[x];
dfs2(y,x);
}
}
void dfs3(int x,int fa){
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y==fa)continue;
sum[y]=(sum1-(b[y]-b[x]))/;
dfs3(y,x);
siz[x]+=siz[y];
}
if(x!=){
a[x]=sum[x]-siz[x];
siz[x]+=a[x];
}
else{
a[x]=sum1-siz[x];
}
}
void clear(){
sum1=tot=;
for(int i=;i<=n;i++)a[i]=b[i]=sum[i]=siz[i]=head[i]=;
}
int main()
{
// freopen("1.in","r",stdin);
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=,x,y;i<n;i++){
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
scanf("%d",&opt);
if(opt==){
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
sum1+=a[i];
}
dfs(,);
dfs1(,);
for(int i=;i<=n;i++)printf("%lld ",sum[i]);
printf("\n");
}
else{
for(int i=;i<=n;i++){
scanf("%lld",&b[i]);
}
dfs2(,);
sum1+=*b[];
sum1/=(n-);
dfs3(,);
for(int i=;i<=n;i++)printf("%d ",a[i]);
printf("\n");
}
clear();
}
return ;
}

T3题目大意:起点为(0,0),给出步数n,每次可以朝上下左右其中一个方向走一步,问n步的时候停在(0,0)的方案有多少种。

每次给出四种限制条件中的任意一个:

没有限制;只能走x轴非负半轴;只能走坐标轴;只能走x、y轴非负半轴以及第一象限。

考试的时候没什么时间了【在T2的自造高斯消元浪费了很久……】,写只走x轴非负半轴的时候不知道为什么打爆了计算组合数,写只走坐标轴的情况又死活弄不出来,最后愤怒地写了个四种情况通用的三维DP,居然拿了50分,三道题最高分…

对于没有限制的情况,和前两天的visit这道题思路一样。枚举左右走的步数为i,因为在n步里面选i步左右走【i为偶数】,在i步里面选i/2步朝左走,在n-i步里面朝上走,最后得出式子:

C(n,i)*C(i,i/2)*C(n-i,(n-i)/2)

对于只能走x轴非负半轴,显然是一个向左走不能超过向右走,类似于出栈不能多于进栈的问题,即卡特兰数。因为向左走向右走步数一共为n,求cat(n/2)。

对于只能走x、y轴非负半轴以及第一象限,会发现这里也是限制的向左走不能超过向右走,并且向下走不能超过向上走。枚举左右走的步数i【i为偶数】,同时限制左右和上下。即对于每一个i,求出cat(i/2)*cat((n-i)/2)*C(n,i)

最后对于只能走坐标轴,看数据范围n<=1000考虑DP。

DP是从前往后推的,那么设一个ans数组表示走i步回到原点的方案数。对于一个n步的方案,可以拆分成两个过程:从原点走i步,除了第i步中间不再回到原点+随便走n-i步回到原点。前面的这i步的方案数是cat(i/2-1),减一是因为catalan数表示的是可以回到原点的,那么就让这i步中先走一步出原点【之后还要走一步回来】,这样catalan的意义中最多回到走出来的这一个点,满足条件。随便走n-i步回到原点,就是ans[n-i]。枚举所有i【i为偶数】即可做到不重不漏。DP方程:ans[i]=∑ans[j]*car(j/2-1)。

阶乘和阶乘的逆元要预处理出来,做到O(1)计算catalan数和组合数【我改题的时候智障地先打了个分解质因数,T得比原来的50分还低】。

到这里四种情况分别讨论完,这题是个四合一问题。

代码:

#include<iostream>
#include<cstdio>
using namespace std;
const long long mod=;
int n,opt;
long long rec[],inv[],f[];
long long ks(long long x,long long k){
long long num=;
while(k){
if(k&)num=num%mod*x%mod;
x=x%mod*x%mod;
k>>=;
}
return num;
}
void work(int x){
inv[]=rec[]=rec[]=;
for(int i=;i<=x;i++)rec[i]=(rec[i-]%mod*(long long)i%mod)%mod;
inv[x]=ks(rec[x],mod-);
for(int i=x-;i>=;i--)inv[i]=(inv[i+]%mod*(long long)(i+)%mod)%mod;
}
long long cat(long long x){
if(x==)return ;
return((rec[*x]*inv[x])%mod*inv[x+])%mod;
}
int main()
{
scanf("%d%d",&n,&opt);
work(n);
if(opt==){
printf("%lld",cat(n/));
}
else if(opt==){
f[]=;
for(int i=;i<=n;i+=){
for(int j=;j<=i;j+=){
f[i]=(f[i]+f[i-j]%mod*%mod*cat(j/-)%mod)%mod;
}
}
printf("%lld",f[n]);
}
else if(opt==){
long long ans=;
for(int k=;k<=n;k+=){
long long ans1=;
ans1=ans1*cat(k/)%mod;
ans1=ans1*cat((n-k)/)%mod;
ans1=ans1*rec[n]%mod*inv[k]%mod*inv[n-k]%mod;
ans=(ans+ans1)%mod;
}
printf("%lld",ans);
}
else{
long long ans=;
for(int k=;k<=n;k+=){
long long ans1=;
ans1=ans1*rec[n]%mod*inv[k/]%mod*inv[k/]%mod*inv[(n-k)/]%mod*inv[(n-k)/]%mod;
ans=(ans+ans1)%mod;
}
printf("%lld",ans);
}
return ;
}

反思…想了想,写一篇游记吧。那么就到这里了。

2019.7.27 NOIP模拟测试9 反思总结的更多相关文章

  1. 2019.8.1 NOIP模拟测试11 反思总结

    延迟了一天来补一个反思总结 急匆匆赶回来考试,我们这边大家的状态都稍微有一点差,不过最后的成绩总体来看好像还不错XD 其实这次拿分的大都是暴力[?],除了某些专注于某道题的人以及远程爆踩我们的某学车神 ...

  2. 2019.8.14 NOIP模拟测试21 反思总结

    模拟测试20的还没改完先咕着 各种细节问题=错失190pts T1大约三分钟搞出了式子,迅速码完,T2写了一半的时候怕最后被卡评测滚去交了,然后右端点没有初始化为n…但是这样还有80pts,而我后来还 ...

  3. 2019.8.9 NOIP模拟测试15 反思总结

    日常爆炸,考得一次比一次差XD 可能还是被身体拖慢了学习的进度吧,虽然按理来说没有影响.大家听的我也听过,大家学的我也没有缺勤多少次. 那么果然还是能力问题吗……? 虽然不愿意承认,但显然就是这样.对 ...

  4. 2019.7.29 NOIP模拟测试10 反思总结【T2补全】

    这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...

  5. 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】

    [题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...

  6. 2019.8.12 NOIP模拟测试18 反思总结

    写个博客总是符合要求的对吧 回来以后第一次悄悄参加考试,昨天全程围观… 然后喜提爆炸120分wwwwwwwww T1用了全机房最慢的写法,导致改掉死循环T掉的一个点以后还是死活过不了最后一个点.T2全 ...

  7. 2019.8.10 NOIP模拟测试16 反思总结【基本更新完毕忽视咕咕咕】

    一如既往先放代码,我还没开始改… 改完T1滚过来了,先把T1T2的题解写了[颓博客啊] 今天下午就要走了,没想到还有送行的饯别礼,真是欣喜万分[并没有] 早上刚码完前面的总结,带着不怎么有希望的心情开 ...

  8. 2019.9.27 csp-s模拟测试53 反思总结

    这个起名方式居然还有后续?! 为什么起名不是连续的?! T1想了半天,搞出来了,结果数组开小[其实是没注意范围].T2概率期望直接跳,后来翻回来写发现自己整个理解错了期望的含义[何].T3错误想到赛道 ...

  9. 2019.8.13 NOIP模拟测试19 反思总结

    最早写博客的一次∑ 听说等会儿还要考试[真就两天三考啊],教练催我们写博客… 大约是出题最友好的一次[虽然我还是炸了],并且数据也非常水…忽视第三题的锅的话的确可以这么说.但是T3数据出锅就是你的错了 ...

随机推荐

  1. poj 3682 King Arthur's Birthday Celebration (期望dp)

    传送门 解题思路 第一问比较简单,设$f[i]​$表示扔了$i​$次正面向上的硬币的期望,那么有转移方程 : $f[i]=f[i]*(1-p)+f[i-1]*p+1​$,意思就是$i​$次正面向上可以 ...

  2. react antd样式按需加载配置以及与css modules模块化的冲突问题

    通过create-react-app脚手架生成一个项目 然后运行npm run eject 把webpack的一些配置从react-scripts模块弹射出来, 方便自己手工增减,暴露出来的配置文件在 ...

  3. PAT甲级——A1073 Scientific Notation

    Scientific notation is the way that scientists easily handle very large numbers or very small number ...

  4. PAT甲级——A1009 Product of Polynomials

    This time, you are supposed to find A×B where A and B are two polynomials. Input Specification: Each ...

  5. 《DSP using MATLAB》Problem 8.2

    代码: %% ------------------------------------------------------------------------ %% Output Info about ...

  6. 怎么解决VirtualBox无法安装增强工具

    点击「设备」-「安装增强功能」,然后就弹出下面这个东西,百度和 bing 了很久,终于解决啦~ Unable to insert the virtual optical disk D:\Program ...

  7. Unity 用代码设置UGUI的渲染层级

    用代码设置UGUI渲染无非和三个API有关: 1.SetAsFirstSibling(); 2.SetAsLastSibling(); 3.SetSiblingIndex(n) SetAsFirstS ...

  8. php 随意参数方法的使用

    1, 用到的PHP函数: func_get_arg() / func_get_args()/ func_num_args 2, func_get_arg(index) :根据索引取得参数具体值     ...

  9. 玩转xargs

    xargs命令可以把标准输入数据转换成命令行参数.也可以将单行或多行文本输入转换成其他格式,是构建单行命令的重要组件之一. xargs命令应该紧跟在管道操作符之后,以stdin作为主要的源数据流,使用 ...

  10. Django项目:CRM(客户关系管理系统)--85--75PerfectCRM实现CRM扩展权限

    # sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...