日期:

八月二日

 总分:

300分

 难度:

提高 ~ 省选

 得分:

40分(又炸蛋了!!)

题目列表:

T1:分手是祝愿

T2:残缺的字符串

T3:树点涂色

赛后心得:

哎,T1求期望,放弃。

看T2像是 KMP 打完发现并不可做,有感觉像是 FFT,放弃

T3我打了个树剖套线段树,调了好久,发现修改操作处理不了,又想到 LCT……

比赛结束!!…… MMP

题解:

T1:分手是祝愿

期望dp,首先,最优解肯定是从大到小,有开的灯就把它按灭

(因为不按的话,编号小的不会对大的有影响,所以会导致这盏灯一直亮着)

不考虑 k,f[i] 表示最优 i 步按得次数的期望。

有 i 种情况能按到对的按钮,n-i 种按错,则状态转移方程:

$$ f_i=\frac{i}{n}+\frac{n-i}{n}(1+f_i+f_{i+1}) $$

(n个开关,i个正确,其他n-i个会增加一个错误,需f[n+1]+f[n]次操作变到i-1)

化简得:

$$ f_i=\frac{n+(n-i)f_{i+1}}{i} $$

显然 f[n]=1,k 以下也为1,直接递推求解。

最后 $ans=\sum_{i=1}^n f_i$

CODE:

 #include<iostream>
#include<cstdio>
#include<vector>
using namespace std; #define mod 100003LL
int n,k,cnt,ans,fac,inv[];
int g[],f[];
bool vis[];
vector<int> fc[]; int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++)scanf("%d",vis+i);
fac=inv[]=inv[]=;
for(int i=;i<=n;i++){
inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod;
fac=1LL*fac*i%mod;
}
for(int i=;i<=n;i++)
for(int j=i;j<=n;j+=i)fc[j].push_back(i);
for(int i=n;i>=;i--)
if(vis[i]){
for(int j=;j<fc[i].size();j++)
vis[fc[i][j]]^=;
cnt++;
}
if(cnt<=k){
printf("%d\n",1LL*cnt*fac%mod);
return ;
}
g[n]=;
for(int i=;i<=k;i++)g[i]=;
for(int i=n-;i>k;i--)g[i]=(1LL*(n-i)*g[i+]%mod+n)*inv[i]%mod;
for(int i=cnt;i>=;i--)(ans+=g[i])%=mod;
printf("%d\n",1LL*ans*fac%mod);
}

T2:残缺的字符串

看起来像是KMP,实际上是FFT。

题解戳这里,我认为他讲的已经很清楚了!

CODE:

 #include<iostream>
#include<cstdio>
#include<complex>
using namespace std; const double PI=acos(-);
typedef complex<long double> cmplx;
int n,m,bit=,rev[],ans[];
cmplx a[],b[];
char A[],B[]; void get_rev(){
while(bit<=n+m)bit<<=;
for(int i=;i<bit;i++)
rev[i]=(rev[i>>]>>)|(i&)*(bit>>);
} void FFT(cmplx a[],int dft){
for(int i=;i<bit;i++)
if(i<rev[i])swap(a[i],a[rev[i]]);
for(int i=;i<bit;i<<=){
cmplx W=exp(cmplx(,dft*PI/i));
for(int j=;j<bit;j+=i<<){
cmplx w(,);
for(int k=j;k<i+j;k++,w*=W){
cmplx x=a[k];
cmplx y=w*a[k+i];
a[k]=x+y,a[k+i]=x-y;
}
}
}
if(dft==-)for(int i=;i<bit;i++)a[i]/=bit;
} int main(){
scanf("%d%d",&m,&n);
scanf("%s%s",A,B);
for(int i=;i<m;i++)
if(A[i]!='*')a[m-i-]=(long double)1.0/(A[i]-'a'++1e3);
for(int i=;i<n;i++)
if(B[i]!='*')b[i]=(long double)B[i]-'a'++1e3;
get_rev();
FFT(a,),FFT(b,);
for(int i=;i<bit;i++)a[i]*=b[i];
FFT(a,-);
for(int i=m-;i<=n-;i++){
int x=a[i].real()+0.25;
if(fabs(a[i].real()-x)<1e-){
ans[++ans[]]=i-m+;
}
}
printf("%d\n",ans[]);
for(int i=;i<=ans[];i++)
printf("%d ",ans[i]);
}

其实这种解法像 Hash 一样有几率发生碰撞的,可能小数加小数,变为整数,但如同 Hash 正确率够高,不用担心。

卡精度啊!!我用了 long double 慢的像屎一样MMP

T3:树点涂色

LCT+线段树

题解戳这里

CODE:

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; #define lch ch[0]
#define rch ch[1]
int n,m,opt,x,y,cnt,tot=,h[];
int dep[],siz[],son[];
int tid[],rak[],tp[],fa[];
int maxv[],add[];
struct Edge{
int x,next;
}e[];
struct Splay{
int fa,ch[];
}v[]; inline void add_edge(int x,int y){
e[++tot].x=y;
e[tot].next=h[x],h[x]=tot;
} void dfs1(int x,int father,int deep){
siz[x]=,fa[x]=father,dep[x]=deep;
v[x].fa=father;
for(int i=h[x];i;i=e[i].next){
if(e[i].x==father)continue;
dfs1(e[i].x,x,deep+);
siz[x]+=siz[e[i].x];
if(siz[e[i].x]>siz[son[x]])son[x]=e[i].x;
}
} void dfs2(int x,int top){
tid[x]=++cnt,rak[cnt]=x,tp[x]=top;
if(son[x])dfs2(son[x],top);
for(int i=h[x];i;i=e[i].next){
if(e[i].x==fa[x]||e[i].x==son[x])continue;
dfs2(e[i].x,e[i].x);
}
} void pushdown(int o){
add[o<<]+=add[o];
add[o<<|]+=add[o];
maxv[o<<]+=add[o];
maxv[o<<|]+=add[o];
add[o]=;
} void build(int o,int l,int r){
if(r-l==){
maxv[o]=dep[rak[l]]+;
}else{
int mid=l+r>>;
build(o<<,l,mid),build(o<<|,mid,r);
maxv[o]=max(maxv[o<<],maxv[o<<|]);
}
} void update(int o,int l,int r,int x,int y,int a){
if(l>=x&&r<=y){
add[o]+=a,maxv[o]+=a;
}else{
pushdown(o);
int mid=l+r>>;
if(x<mid)update(o<<,l,mid,x,y,a);
if(y>mid)update(o<<|,mid,r,x,y,a);
maxv[o]=max(maxv[o<<],maxv[o<<|]);
}
} int query(int o,int l,int r,int x,int y){
if(l>=x&&r<=y)return maxv[o];
pushdown(o);
int mid=l+r>>;
int ans=;
if(x<mid)ans=max(ans,query(o<<,l,mid,x,y));
if(y>mid)ans=max(ans,query(o<<|,mid,r,x,y));
return ans;
} int LCA(int x,int y){
while(tp[x]!=tp[y]){
if(dep[tp[x]]<dep[tp[y]])swap(x,y);
x=fa[tp[x]];
}
if(dep[x]>dep[y])swap(x,y);
return x;
} inline bool isroot(int x){
return v[v[x].fa].lch!=x&&v[v[x].fa].rch!=x;
} inline void rotate(int x){
int y=v[x].fa,z=v[y].fa;
if(!isroot(y))v[z].ch[v[z].rch==y]=x;
v[x].fa=z;
bool k=v[y].rch==x;
v[y].ch[k]=v[x].ch[k^];
if(v[x].ch[k^])v[v[x].ch[k^]].fa=y;
v[x].ch[k^]=y,v[y].fa=x;
} inline void splay(int x){
while(!isroot(x)){
int y=v[x].fa,z=v[y].fa;
if(!isroot(y)){
if(v[y].lch==x^v[z].lch==y)rotate(x);
else rotate(y);
}
rotate(x);
}
} void access(int x){
for(int y=;x;y=x,x=v[x].fa){
splay(x);
if(v[x].rch){
int k=v[x].rch;
while(v[k].lch)k=v[k].lch;
update(,,n+,tid[k],tid[k]+siz[k],);
}
v[x].rch=y;
if(y){
int k=y;
while(v[k].lch)k=v[k].lch;
update(,,n+,tid[k],tid[k]+siz[k],-);
}
}
} int main(){
// puts("silly pcj!!!")
scanf("%d%d",&n,&m);
for(int i=;i<n;i++){
scanf("%d%d",&x,&y);
add_edge(x,y);
add_edge(y,x);
}
dfs1(,,),dfs2(,);
build(,,n+);
for(int i=;i<=m;i++){
scanf("%d",&opt);
if(opt!=)scanf("%d",&x);
else scanf("%d%d",&x,&y);
if(opt==)access(x);
if(opt==){
int lca=LCA(x,y);
int sum1=query(,,n+,tid[x],tid[x]+);
int sum2=query(,,n+,tid[y],tid[y]+);
int sum=query(,,n+,tid[lca],tid[lca]+);
printf("%d\n",sum1+sum2-*sum+);
}
if(opt==)
printf("%d\n",query(,,n+,tid[x],tid[x]+siz[x]));
}
}

2017.8.2 Noip2018模拟测试赛(十八)的更多相关文章

  1. 2017.8.1 Noip2018模拟测试赛(十七)

    日期: 八月第一天  总分: 300分  难度: 提高 ~ 省选    得分: 100分(不应该啊!) 题目目录: T1:战争调度 T2:选数 T3:由乃的OJ 赛后心得: MMP,首先第一题花了大概 ...

  2. 2018.7.31 Noip2018模拟测试赛(十六)

     日期: 七月最后一天  总分: 300分  难度: 提高 ~ 省选  得分: 30分(少的可怜) 我太弱了:(题目目录) T1:Mushroom追妹纸 T2:抵制克苏恩 T3:美味 失分分析:(QA ...

  3. 2018.8.7 Noip2018模拟测试赛(二十)

    日期: 八月七号  总分: 300分  难度: 提高 ~ 省选    得分: 100分(呵呵一笑) 题目列表: T1:SS T2:Tree Game T3:二元运算 赛后反思: Emmmmmm…… 开 ...

  4. 2018.8.6 Noip2018模拟测试赛(十九)

    日期: 八月六号  总分: 300分  难度: 提高 ~ 省选    得分: 10分(MMP) 题目目录: T1:Tree T2:异或运算 T3:Tree Restoring 赛后反思: Emmmmm ...

  5. 2018.8.8 Noip2018模拟测试赛(二十一)

    日期: 八月七号  总分: 300分  难度: 提高 ~ 省选    得分: 112分(OvO) 题目目录: T1:幸福的道路 T2:Solitaire T3:Flags 赛后心得: 第一题裸树d啊! ...

  6. [2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania

    [2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见&quo ...

  7. noi2019模拟测试赛(四十七)

    noi2019模拟测试赛(四十七) T1与运算(and) 题意: ​ 给你一个序列\(a_i\),定义\(f_i=a_1\&a_2\&\cdots\&a_i\),求这个序列的所 ...

  8. [CSP-S模拟测试]:赛(贪心+三分)

    题目描述 由于出题人思维枯竭所以想不出好玩的背景.有$n$个物品,第$i$个物品的价格是$v_i$,有两个人,每个人都喜欢$n$个物品中的一些物品.要求选出正好$m$个物品,满足选出的物品中至少有$k ...

  9. 【2016北京集训测试赛(八)】 crash的数列 (思考题)

    Description 题解 题目说这是一个具有神奇特性的数列!这句话是非常有用的因为我们发现,如果套着这个数列的定义再从原数列引出一个新数列,它居然还是一样的...... 于是我们就想到了能不能用多 ...

随机推荐

  1. Python re module (regular expressions)

    regular expressions (RE) 简介 re模块是python中处理正在表达式的一个模块 r"""Support for regular expressi ...

  2. 性能优化之MySQL优化(慕课)

    MySQL数据库优化 1-1MySQL优化简介 数据库优化的目的 避免出现页面访问错误 由于数据库连接timeout产生5XX错误 由于慢查询造成页面无法加载 由于阻塞造成数据无法提交 增加数据库的稳 ...

  3. React组件自适应窗口宽高

    很多时候我们需要组件能够根据窗口变化改变宽高,有时候可以使用css,有时候需要随数据调整则使用js计算. 比如说,当我们在页面中放置一个iframe时,我们希望它的宽高随着其父元素or窗口的变化而变化 ...

  4. Linux下如何通过命令检查网卡是否插上网线

    How To:Linux下如何通过命令检查网卡是否插上网线   主要工具为ethtool来检查,主要关注的字段为"Link detected",注意如下的输出,其中em4实际物理上 ...

  5. Windows 10 建立wifi热点

    如果当前是台式机那么需要一个usb的无线网卡,这里要注意如果你是使用台式机并且通过有线的方式上网,但是你的无线网卡适配器不能在禁用状态. 这里首先打开[运行]输入cmd,打开cmd(注意,这里要使用管 ...

  6. Docker系列一:Docker的介绍和安装

    Docker介绍 Docker是指容器化技术,用于支持创建和实验Linux Container.借助Docker,你可以将容器当做重量轻.模块化的虚拟机来使用,同时,你还将获得高度的灵活性,从而实现对 ...

  7. SpringMVC 项目中引用其他 Module 中的方法

    1. 将要引用的Module 引入项目中 2. 在主Module中添加依赖, 3. 被引用的类必须放在 Module 中/src/下的某个package中,否则引用不到(重要)

  8. 使用jmeter做简单的压测(检查点、负载设置、聚合报告)

    1.添加断言(检查点) 在需要压测的接口下添加--断言--响应断言,取接口响应中包含有的数据即可 检查点HTTP请求-->断言-->响应断言1.名称.注释2.Apply to//作用于哪里 ...

  9. ultraedit编辑器破解版下载

    ultraedit一款功能丰富的网站建设软件,需要的朋友可以看看. 百度百科:UltraEdit 是一套功能强大的文本编辑器,可以编辑文本.十六进制.ASCII 码,完全可以取代记事本(如果电脑配置足 ...

  10. python并发编程之线程(创建线程,锁(死锁现象,递归锁),GIL锁)

    什么是线程 进程:资源分配单位 线程:cpu执行单位(实体),每一个py文件中就是一个进程,一个进程中至少有一个线程 线程的两种创建方式: 一 from threading import Thread ...