2019.7.27 NOIP模拟测试9 反思总结
先来整理题目
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 反思总结的更多相关文章
- 2019.8.1 NOIP模拟测试11 反思总结
延迟了一天来补一个反思总结 急匆匆赶回来考试,我们这边大家的状态都稍微有一点差,不过最后的成绩总体来看好像还不错XD 其实这次拿分的大都是暴力[?],除了某些专注于某道题的人以及远程爆踩我们的某学车神 ...
- 2019.8.14 NOIP模拟测试21 反思总结
模拟测试20的还没改完先咕着 各种细节问题=错失190pts T1大约三分钟搞出了式子,迅速码完,T2写了一半的时候怕最后被卡评测滚去交了,然后右端点没有初始化为n…但是这样还有80pts,而我后来还 ...
- 2019.8.9 NOIP模拟测试15 反思总结
日常爆炸,考得一次比一次差XD 可能还是被身体拖慢了学习的进度吧,虽然按理来说没有影响.大家听的我也听过,大家学的我也没有缺勤多少次. 那么果然还是能力问题吗……? 虽然不愿意承认,但显然就是这样.对 ...
- 2019.7.29 NOIP模拟测试10 反思总结【T2补全】
这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...
- 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】
[题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...
- 2019.8.12 NOIP模拟测试18 反思总结
写个博客总是符合要求的对吧 回来以后第一次悄悄参加考试,昨天全程围观… 然后喜提爆炸120分wwwwwwwww T1用了全机房最慢的写法,导致改掉死循环T掉的一个点以后还是死活过不了最后一个点.T2全 ...
- 2019.8.10 NOIP模拟测试16 反思总结【基本更新完毕忽视咕咕咕】
一如既往先放代码,我还没开始改… 改完T1滚过来了,先把T1T2的题解写了[颓博客啊] 今天下午就要走了,没想到还有送行的饯别礼,真是欣喜万分[并没有] 早上刚码完前面的总结,带着不怎么有希望的心情开 ...
- 2019.9.27 csp-s模拟测试53 反思总结
这个起名方式居然还有后续?! 为什么起名不是连续的?! T1想了半天,搞出来了,结果数组开小[其实是没注意范围].T2概率期望直接跳,后来翻回来写发现自己整个理解错了期望的含义[何].T3错误想到赛道 ...
- 2019.8.13 NOIP模拟测试19 反思总结
最早写博客的一次∑ 听说等会儿还要考试[真就两天三考啊],教练催我们写博客… 大约是出题最友好的一次[虽然我还是炸了],并且数据也非常水…忽视第三题的锅的话的确可以这么说.但是T3数据出锅就是你的错了 ...
随机推荐
- lvs + keepalived + nginx + tomcat高可用负载反向代理服务器配置(一) 简介
一. 为什么这样构架 1. 系统高可用性 2. 系统可扩展性 3. 负载均衡能力 LVS+keepalived能很好的实现以上的要求,keepalived提供健康检查,故障转移,提高系统的可用性!采用 ...
- VS2005进行WORD文档开发
折腾了将近一个月的WORD文档开发终于告一段落.这件事已经很多大牛已经做过了.并且很多方法都已经非常详细,提供的资料也非常齐全.不过由于时间的久远并且较为散乱.所以我在学习时间过程中还是走了一些些弯路 ...
- Codeforces 442B. Andrey and Problem
time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...
- [转]绑定到异步的ObservableCollection
在进行WPF开发过程中,需要从一个新的线程中操作ObservableCollection,结果程序抛出一个NotSupportedException的错误: This type of Collecti ...
- 微信小程序之组件的集合(五)
这个是学习复杂的组件的封装的,在课程中,主要实现的是书单上方的搜索功能组件的开发,这个应该是较之前的组件是有一定难度的,但是现在学到现在,感觉前端的内容和后端的内容比较起来,还是比较容易的,而且好多内 ...
- 【codeforces 507E】Breaking Good
[题目链接]:https://vjudge.net/contest/164884#problem/D [题意] 给你一张图; 图中有些路是完好的;但有些路还没修好; 先不管路有没有修好; 问你从起点到 ...
- bootstrap面包屑在ie8下显示重叠,鼠标点击显示效果正常
ie8下加载后的显示 点击之后的显示 主要是li标签宽度auto引起的,可以设置li标签的最小宽度 <ol class="breadcrumb"> <li id= ...
- Interface Builder: What are the UIView's Layout iOS 6/7 Deltas for?
up vote57down votefavorite 19 I just noticed the iOS 6/7 Delta property found under the UIView's str ...
- CentOS设置打开终端快捷键
- LRU Cache数据结构简介
什么是LRU Cache LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法. 什么是Cache?狭义的Cache指的是位于CPU和主存间的快速RAM ...