2017.8.2 Noip2018模拟测试赛(十八)
日期: |
八月二日 |
总分: |
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模拟测试赛(十八)的更多相关文章
- 2017.8.1 Noip2018模拟测试赛(十七)
日期: 八月第一天 总分: 300分 难度: 提高 ~ 省选 得分: 100分(不应该啊!) 题目目录: T1:战争调度 T2:选数 T3:由乃的OJ 赛后心得: MMP,首先第一题花了大概 ...
- 2018.7.31 Noip2018模拟测试赛(十六)
日期: 七月最后一天 总分: 300分 难度: 提高 ~ 省选 得分: 30分(少的可怜) 我太弱了:(题目目录) T1:Mushroom追妹纸 T2:抵制克苏恩 T3:美味 失分分析:(QA ...
- 2018.8.7 Noip2018模拟测试赛(二十)
日期: 八月七号 总分: 300分 难度: 提高 ~ 省选 得分: 100分(呵呵一笑) 题目列表: T1:SS T2:Tree Game T3:二元运算 赛后反思: Emmmmmm…… 开 ...
- 2018.8.6 Noip2018模拟测试赛(十九)
日期: 八月六号 总分: 300分 难度: 提高 ~ 省选 得分: 10分(MMP) 题目目录: T1:Tree T2:异或运算 T3:Tree Restoring 赛后反思: Emmmmm ...
- 2018.8.8 Noip2018模拟测试赛(二十一)
日期: 八月七号 总分: 300分 难度: 提高 ~ 省选 得分: 112分(OvO) 题目目录: T1:幸福的道路 T2:Solitaire T3:Flags 赛后心得: 第一题裸树d啊! ...
- [2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania
[2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见&quo ...
- noi2019模拟测试赛(四十七)
noi2019模拟测试赛(四十七) T1与运算(and) 题意: 给你一个序列\(a_i\),定义\(f_i=a_1\&a_2\&\cdots\&a_i\),求这个序列的所 ...
- [CSP-S模拟测试]:赛(贪心+三分)
题目描述 由于出题人思维枯竭所以想不出好玩的背景.有$n$个物品,第$i$个物品的价格是$v_i$,有两个人,每个人都喜欢$n$个物品中的一些物品.要求选出正好$m$个物品,满足选出的物品中至少有$k ...
- 【2016北京集训测试赛(八)】 crash的数列 (思考题)
Description 题解 题目说这是一个具有神奇特性的数列!这句话是非常有用的因为我们发现,如果套着这个数列的定义再从原数列引出一个新数列,它居然还是一样的...... 于是我们就想到了能不能用多 ...
随机推荐
- hash join
hash join是oracle里面一个非常强悍的功能,当做hash join时,oracle会选择一个表作为驱动表,先根据过滤条件排除不必要的数据,然后将结果集做成hash表,放入进程的hash a ...
- 在Keras中导入测试数据的方法
https://blog.csdn.net/ethantequila/article/details/80322425?utm_source=blogxgwz2
- 【状态压缩dp】1195: [HNOI2006]最短母串
一个清晰的思路就是状压dp:不过也有AC自动机+BFS的做法 Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T ...
- 【TCP/IP】【网络基础】网页访问流程
引用自 <鸟哥的linux私房菜> http://cn.linux.vbird.org/linux_server/0110network_basic_1.php#ps7 那 TCP/IP ...
- Struts2和Spring MVC 区别 今天面试被问到了
虽然说没有系统的学习过Spring MVC框架, 但是工作这么长时间, 基本上在WEB层使用的都是Spring MVC, 自己觉得Struts2也是一个不错的WEB层框架, 这两种框架至今自己还未有比 ...
- drf 解析器,响应器,路由控制
解析器 作用: 根据请求头 content-type 选择对应的解析器对请求体内容进行处理. 有application/json,x-www-form-urlencoded,form-data等格式 ...
- jmeter接口测试 ——学习笔记
JMETER常用操作 1.jmeter做http脚本 Http请求页面内容介绍 添加cookie 线程组-添加-配置元件--HTTP Cookie管理器 添加权限验证 不能使用普通用户修改学生金币,接 ...
- 建立,查询二叉树 hdu 5444
Elven Postman Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
- HDU 3315 KM My Brute
参考题解 二分图的最优匹配.图很容易建立.再处理相似度的时候.把每个权值扩大100倍.然后再对i==j时 特殊标记.使他们的权值再++1.后面选择的时候就很容易挑出.按原匹配 匹配的个数. 100*( ...
- 当列表推导式遇到lambda(匿名函数)
Python这么优雅的语言,我也是醉了...... 事情由一段代码引发,请看: 上述的列表推导式+lambda表达式+for循环,他们碰撞出来的结果搞的人晕头转向,咱们逐步来分析一下他们到底是个什么鬼 ...