[考试反思]0924csp-s模拟测试51:破碎
总参赛人数:15
有点菜。
不知道是撞了什么大运没有滚出A层。
但是一回到A层就暴露出了一个大问题:码速。
不是调试速度,,就是纯粹码的速度。。。
边讲考试状态边说吧。。。
上来肝T1。一看,是个换根的题?没做过啊。。。
LCT?啊?还要维护子树???这不是之前看的top_tree吗?
600行的玩意考场上还是不要考虑的。
然后就走上了一条不归路。
一个真正坑的暴力就是暴力的码量和调试难度都比正解还高。
幸而都是打熟了的东西,板子出锅倒不多。
但是纯粹码出来用了一个小时???感觉状态也不是很好。
然后没有过大样例,调了一阵没找出来然后决定先看T2T3。
其实出锅的地方是我想尝试改一下板子的某一个地方还坚定地认为它是对的。
T3只要有一点二进制思想就会的特别蠢的dp打出来,尝试优化,明知道它是个多项式。
但因为不会母函数所以即使打了NTT也只会多13分,而时间不够了就没有打(两小时了三道题还都没有分)
随便扔了个暴力dp上去,赶紧回去调T1。
中途给T2打表尝试找规律,然后脸去上厕所,回来的时候看我还在打表发呆就笑话我。
我也不知道他在笑话什么,大概意思就是他T1切了T2也找到规律了吧。。与我无瓜。
最后回T1,怕爆零于是打了一个更暴力的(21分)然后与目标40分的对拍。
打暴力+对拍又码了好久(大半个小时?)。然后调出来倒挺快的。但是这时候只剩下21分钟了。
这时候估计就算想出来哪道题了也打不完了吧。。。于是把T2的表扔了上去,没开long long丢了16分。
期望40+13+46=99。实际86。
可以发现。我的最高期望得分还不如A掉一个然后剩下两个都爆零。
说白了这次考试过程看下来的确很忙但是有一个特点:
没时间思考。一直在码。
这就很不妙了,码到底不出锅还不如认认真真打一道题。。。
看全机房最胖的三个都把T1A了总分就是前三名。
OI主要考的不是码力,真正要区分的就是脑子!
其实我也不能说是不会。T1的代码框架也已经出来了,再想想肯定不会局限与40分。
因为正解并不鬼畜,虽然新颖一些,但是难度并不高。
要思考。
说是在的到底为什么没有思考呢?其实原因倒有很多:首先有点不适应A卷,然后对数据结构有些害怕,还有潜意识里貌似就把自己拍死在暴力上了。
说白了就一句:不要怂,动脑子!
某种意义上,没有思考的话,可能就是浪费了一套卷子。
和前面的考试有些不一样,有时候是想了太久没码,有时候是码了太久没想。
积累经验,自行权衡。
第一次回A卷就不说什么了,希望下一次能不要这么惨吧。。。
T1:Tree
换根是假的。
拍在dfs序上维护子树。
分类讨论要操作的点和当前的根的关系来判断要修改的dfs序区间。
没有那么难。
#include<cstdio>
int n,q,cnt,fir[],l[],to[],f[][],tim,root=;
long long W[];int re[],dfn[],rdfn[],dep[];
struct Segment_Tree{
int cl[],cr[];long long lz[],w[];
void build(int p,int l,int r){
cl[p]=l;cr[p]=r;
if(l==r){w[p]=W[re[l]];return;}
build(p<<,l,l+r>>);
build(p<<|,(l+r>>)+,r);
w[p]=w[p<<]+w[p<<|];
}
void down(int p){//printf("down:%d\n",p);
lz[p<<]+=lz[p];lz[p<<|]+=lz[p];
w[p<<]+=lz[p]*(cr[p<<]-cl[p<<]+);
w[p<<|]+=lz[p]*(cr[p<<|]-cl[p<<|]+);
lz[p]=;w[p]=w[p<<]+w[p<<|];
}
void add(int p,int l,int r,long long W){//printf("%d %d %d %lld\n",p,cl[p],cr[p],W);
if(l<=cl[p]&&cr[p]<=r){lz[p]+=W;w[p]+=W*(cr[p]-cl[p]+);return;}
if(lz[p])down(p);
if(l<=cr[p<<])add(p<<,l,r,W);
if(r>=cl[p<<|])add(p<<|,l,r,W);
w[p]=w[p<<]+w[p<<|];
}
long long ask(int p,int l,int r){//printf("ask:%d %d %d %lld\n",p,l,r,lz[p]);
if(l<=cl[p]&&cr[p]<=r)return w[p];
if(lz[p])down(p);
return (l<=cr[p<<]?ask(p<<,l,r):)+(r>=cl[p<<|]?ask(p<<|,l,r):);
}
}tree;
void dfs(int p){
dfn[p]=++tim;re[tim]=p;dep[p]=dep[f[p][]]+;
for(int i=;i<=;++i)f[p][i]=f[f[p][i-]][i-];
for(int i=fir[p];i;i=l[i])if(to[i]!=f[p][])f[to[i]][]=p,dfs(to[i]);
rdfn[p]=tim;
}
long long read(register long long p=,register char ch=getchar(),register int nt=){
while(ch<''||ch>''){if(ch=='-')nt=-;ch=getchar();}
while(ch>=''&&ch<='')p=(p<<)+(p<<)+ch-'',ch=getchar();
return p*nt;
}
int lca(int x,int y){
int subdep=dep[x]-dep[y];
if(subdep<)subdep*=-,x^=y^=x^=y;
for(int i=;~i;--i)if(subdep&<<i)x=f[x][i];
if(x==y)return x;
for(int i=;~i;--i)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
return f[x][];
}
int getson(int x,int ff){
int subdep=dep[x]-dep[ff]-;
for(int i=;~i;--i)if(subdep&<<i)x=f[x][i];
return x;
}
void link(int a,int b){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;}
int main(){//freopen("tree2.in","r",stdin);freopen("my.out","w",stdout);
n=read();q=read();
for(int i=;i<=n;++i)W[i]=read();
for(int i=,a,b;i<n;++i)a=read(),b=read(),link(a,b),link(b,a);
dfs();tree.build(,,n);
for(int i=,opt,u,v,a,b,c,S,LCA;i<=q;++i){
opt=read();u=read();long long x;
if(opt==)root=u;
if(opt==){
v=read();x=read();
c=lca(u,v);a=lca(root,u);b=lca(root,v);
if(dep[a]>dep[b])LCA=a;else LCA=b;
if(dep[c]>dep[LCA])LCA=c;
if(LCA==root)tree.add(,,n,x);
else if(dfn[LCA]<=dfn[root]&&rdfn[root]<=rdfn[LCA])tree.add(,,n,x),S=getson(root,LCA),tree.add(,dfn[S],rdfn[S],-x);
else tree.add(,dfn[LCA],rdfn[LCA],x);
}
if(opt==){
if(root==u)printf("%lld\n",tree.ask(,,n));
else if(dfn[u]<=dfn[root]&&rdfn[root]<=rdfn[u])S=getson(root,u),printf("%lld\n",tree.ask(,,n)-tree.ask(,dfn[S],rdfn[S]));
else printf("%lld\n",tree.ask(,dfn[u],rdfn[u]));
}
}
}
思路积累:
- 不要把思路拘束于新学的东西上。
- 能换根的数据结构不多,但是换根不一定真的要重建树,而只是修改了父子关系而已。
- 问题的转化。研究性质。
T2:Function
神仙题。另写题解。
T3:Or
dp[i][j]为已经选了i个数,二进制下已经有了j个1。
#include<cstdio>
#define int long long
#define mod 998244353
int pw[],f[][],n,k,fac[],invv[],inv[],ans;
int C(int b,int t){return fac[b]*inv[t]%mod*inv[b-t]%mod;}
main(){
scanf("%lld%lld",&n,&k);
invv[]=fac[]=fac[]=inv[]=inv[]=f[][]=pw[]=;pw[]=;
for(int i=;i<=k;++i)fac[i]=fac[i-]*i%mod,invv[i]=mod-mod/i*invv[mod%i]%mod,inv[i]=inv[i-]*invv[i]%mod,pw[i]=(pw[i-]<<)%mod;
for(int i=;i<=n;++i)for(int j=i;j<=k;++j){
f[i&][j]=;
for(int t=i-;t<j;++t)f[i&][j]+=f[i&^][t]*C(k-t,j-t)%mod*pw[t]%mod;
f[i&][j]%=mod;//printf("%lld %lld %lld\n",i,j,f[i&1][j]);
}
for(int j=n;j<=k;++j)ans+=f[n&][j];
printf("%lld\n",ans%mod);
}
46分暴力
转移的式子符合卷积形式,NTT做n遍可以多拿13分。
#include<cstdio>
#define int long long
#define mod 998244353
int pw[],f[],n,k,fac[],invv[],inv[],ans,rev[],Inv,invNTT[],bin=;
int pow(int b,int t,int a=){for(;t;t>>=,b=b*b%mod)if(t&)a=a*b%mod;return a;}
void NTT(int *a,int opt){
for(int i=;i<bin;++i)if(rev[i]<i)a[i]^=a[rev[i]]^=a[i]^=a[rev[i]];
for(int mid=;mid<bin;mid<<=)
for(int i=,w=pow(,opt*(mod-)/mid/+mod-);i<bin;i+=mid<<)
for(int j=,wn=;j<mid;++j,wn=wn*w%mod){
int x=a[i+j],y=a[i+j+mid]*wn%mod;
a[i+j]=(x+y)%mod;a[i+j+mid]=(x-y+mod)%mod;
}
if(opt==-)for(int i=;i<bin;++i)a[i]=a[i]*Inv%mod;
}
main(){
scanf("%lld%lld",&n,&k);
invv[]=fac[]=fac[]=inv[]=inv[]=f[]=pw[]=;pw[]=;
while(bin<=k)bin<<=; bin<<=;Inv=pow(bin,mod-);
for(int i=;i<=k;++i)fac[i]=fac[i-]*i%mod,invv[i]=mod-mod/i*invv[mod%i]%mod,inv[i]=inv[i-]*invv[i]%mod,pw[i]=(pw[i-]<<)%mod;
for(int i=;i<=k;++i)invNTT[i]=inv[i];
for(int i=;i<bin;++i)rev[i]=rev[i>>]>>|(i&)*bin>>;
NTT(invNTT,);
for(int i=;i<=n;++i){
for(int s=;s<bin;++s)f[s]=f[s]*pw[s]%mod*fac[k-s]%mod;
NTT(f,);
for(int s=;s<bin;++s)f[s]=f[s]*invNTT[s]%mod;
NTT(f,-);
for(int s=;s<bin;++s)f[s]=f[s]*inv[k-s]%mod;
}
for(int j=;j<=k;++j)ans+=f[j];
printf("%lld\n",ans%mod);
}
59分NTT暴力
NC写的题解看不懂,还要高阶求导做前置知识。
然后用母函数倍增瞎改一下就A了。(题解待补)
#include<cstdio>
#define int long long
#define mod 998244353
int pw[],f[],n,k,fac[],invv[],inv[],ans,rev[],Inv,bin=,re[];
int pow(int b,int t,int a=){for(;t;t>>=,b=b*b%mod)if(t&)a=a*b%mod;return a;}
void NTT(int *a,int opt){
for(int i=;i<bin;++i)if(rev[i]<i)a[i]^=a[rev[i]]^=a[i]^=a[rev[i]];
for(int mid=;mid<bin;mid<<=)
for(int i=,w=pow(,opt*(mod-)/mid/+mod-);i<bin;i+=mid<<)
for(int j=,wn=;j<mid;++j,wn=wn*w%mod){
int x=a[i+j],y=a[i+j+mid]*wn%mod;
a[i+j]=(x+y)%mod;a[i+j+mid]=(x-y+mod)%mod;
}
if(opt==-)for(int i=;i<bin;++i)a[i]=a[i]*Inv%mod;
}
void mul(){
NTT(f,);NTT(re,);
for(int i=;i<bin;++i)f[i]=f[i]*re[i]%mod,re[i]=;
NTT(f,-);
for(int i=k+;i<bin;++i)f[i]=;
}
void G(int N){
if(N==){for(int i=;i<=k;++i)f[i]=inv[i];return;}
G(N>>);
for(int res=,i=;i<=k;++i)re[i]=(res=res*pw[N>>]%mod)*f[i]%mod; mul();
if(N&){for(int res=,i=;i<=k;++i)re[i]=(res=res*pw[N-]%mod)*inv[i]%mod; mul();}
}
main(){
scanf("%lld%lld",&n,&k);
invv[]=fac[]=fac[]=inv[]=pw[]=inv[]=;pw[]=;
while(bin<=k)bin<<=; bin<<=;Inv=pow(bin,mod-);
for(int i=;i<=k;++i)fac[i]=fac[i-]*i%mod,invv[i]=mod-mod/i*invv[mod%i]%mod,inv[i]=inv[i-]*invv[i]%mod,pw[i]=(pw[i-]<<)%mod;
for(int i=;i<bin;++i)rev[i]=rev[i>>]>>|(i&)*bin>>;
G(n);
for(int j=n;j<=k;++j)ans=(ans+f[j]*fac[k]%mod*inv[k-j])%mod;
printf("%lld\n",ans);
}
[考试反思]0924csp-s模拟测试51:破碎的更多相关文章
- [考试反思]0718 NOIP模拟测试5
最后一个是我...rank#11 rank#1和rank#2被外校大佬包揽了. 啊...考的太烂说话底气不足... 我考场上在干些什么啊!!! 20分钟“切”掉T2,又27分钟“切”掉T1 切什么切, ...
- 2019.9.24 csp-s模拟测试51(a) 反思总结
T1:还在头铁,顺便复习了一下lct[虽然这题用不上因为复杂度不对] 头铁结束. 虽然题目存在换根的操作,实际上并不用真的换根. 2操作中求lca的时候只要考虑原树上root和x.y的lca以及x,y ...
- CSP-S 模拟测试 51 题解
考试过程: 惯例先看一遍三道题,T1 一开始反应要求割点,但是这是有向图,肯定不能求割点,康了一下数据范围,有40%是树的,还不错,决定待会在打. 看T2 字符串题,完了我字符串最弱了,肯定只能打暴力 ...
- [CSP-S模拟测试51]题解
错失人生中第一次AK的机会…… A.attack 支配树板子题.考场上发明成功√ 首先支配树上两点路径之间的点都是必经之点,根据这个性质我们就可以yy出建树的方法.跑拓扑,在每个点(设为$x$)即将入 ...
- csp-s模拟测试51(b)attack,tree题解
题面:https://www.cnblogs.com/Juve/articles/11598286.html attack: 支配树裸题? 看一下支配树是什么: 问题:我们有一个有向图(可以有环),定 ...
- [考试反思]0814NOIP模拟测试21
前两名是外校的240.220.kx和skyh拿到了190的[暴力打满]的好成绩. 我第5是170分,然而160分就是第19了. 在前一晚上刚刚爆炸完毕后,心态格外平稳. 想想前一天晚上的挣扎: 啊啊啊 ...
- [考试反思]1109csp-s模拟测试106:撞词
(撞哈希了用了模拟测试28的词,所以这次就叫撞词吧) 蓝色的0... 蓝色的0... 都该联赛了还能CE呢... 考试结束前15分钟左右,期望得分300 然后对拍发现T2伪了写了一个能拿90分的垃圾随 ...
- [考试反思]0909csp-s模拟测试41:反典
说在前面:我是反面典型!!!不要学我!!! 说在前面:向rank1某脸学习,不管是什么题都在考试反思后面稍微写一下题解. 这次是真的真的运气好... 这次知识点上还可以,但是答题策略出了问题... 幸 ...
- [考试反思]0729NOIP模拟测试10
安度因:哇哦. 安度因:谢谢你. 第三个rank1不知为什么就来了.迷之二连?也不知道哪里来的rp 连续两次考试数学都占了比较大的比重,所以我非常幸运的得以发挥我的优势(也许是优势吧,反正数学里基本没 ...
随机推荐
- Openshift yum安装
Openshift yum安装: Yum 安装docker [root@DockerServer openshift]# yum repolist [root@DockerServer openshi ...
- SpringBoot2+Netty打造通俗简版RPC通信框架
2019-07-19:完成基本RPC通信! 2019-07-22:优化此框架,实现单一长连接! 2019-07-24:继续优化此框架:1.增加服务提供注解(带版本号),然后利用Spring框架的在启动 ...
- java中的String是不可变类
String s = "hello "; s += "world"; 这两行代码执行后,原始的String对象中的内容没有变 在这段代码中,s原先指向一个Str ...
- cookie和session,cookie和web storage
一.cookie和session cookie和session的共同之处在于:cookie和session都是用来跟踪浏览器用户身份的会话方式. session指的是访问者从到达某个特定页面到离开为止 ...
- CONVERT用法指南,时间字段截取方法
语法: CONVERT(VARCHAR(7),<字段名称>,121) 时间转字符:select CONVERT(VARCHAR(7),dyxq,121),* from TBYPKC03-- ...
- SQL SERVER数据库,按年、月、日、时、分、秒计算两个时间字段之间的间隔时间样例
使用DATEDIFF(取值,时间字段1,时间字段2) 举例: SELECT DATEDIFF(YEAR,DRYSJ,DCYSJ),* FROM YXHIS2019..TBZYBR2019 --SQL ...
- 由一次线上故障来理解下 TCP 三握、四挥 & Java 堆栈分析到源码的探秘
本文导读: 生产故障场景介绍 TCP 建连三次握手过程 TCP 断连四次挥手过程 结合 Java 堆栈剖析源码 再从堆栈中找到"罪魁祸首" 问题优化方案总结 1.生产故障场景介绍 ...
- 不就是SELECT COUNT语句吗,竟然能被面试官虐的体无完肤
数据库查询相信很多人都不陌生,所有经常有人调侃程序员就是CRUD专员,这所谓的CRUD指的就是数据库的增删改查. 在数据库的增删改查操作中,使用最频繁的就是查询操作.而在所有查询操作中,统计数量操作更 ...
- Node.js新手必须知道的4个JavaScript概念
如果只需要知道一种编程语言就可以构建一个全栈的应用程序,是不是特别了不起?Ryan Dahl为了把这个想法成为现实,创造了node.js.Node.js是建立在Chrome强劲的V8 JavaScri ...
- Vue中Class与Style如何动态绑定
Class 可以通过对象语法和数组语法进行动态绑定: 对象语法: <div v-bind:class="{ active: isActive, 'text-danger': hasEr ...