51nod 省选联测 R2
51nod 省选联测 R2
上场的题我到现在一道都没A,等哪天改完了再写题解吧,现在直接写第二场的。
第二场比第一场简单很多(然而这并不妨碍我不会做)。
A.抽卡大赛:http://www.51nod.com/Challenge/Problem.html#!#problemId=1850
这题非常的神仙。
考试的时候没看见数据范围...以为是1e5,觉得非常不可做。结果其实是200?
$N^4$ 的做法挺好想的,首先枚举一个人,再枚举他的牌,然后计算其他人胜过他的概率,最后做一个 $N^2$ 的DP算答案,这里就不细讲了。
让我们换一下思路,不要再枚举人了,将所有的牌按从大到小排序后直接枚举牌。
下面这部分有一点难理解...在之前的做法中,要计算“i排第j名的概率”,在这里,因为不能枚举人,所以计算的就是“如果出现了一个拿着i这种牌的人,排第j名的概率”。乍一看,这个东西意义何在...但其实还是挺有用的。假设我们可以以 $O(N)$ 的效率从背包中撤出某个物品,那么当计算 $i$ 这个人时就撤掉它自己,算完后再加进去就可以了。因为每次加入一张新牌时,只有一个人“胜过更小的牌的概率”改变了,所以这样做的复杂度是 $N^3$ 的。
最后考虑如何删除背包里的物品:
最初的状态转移:
倒序枚举j,可以消掉一维:
考虑一下边界情况:
也就是说,如果要撤掉一个数,可以直接算出原来的 $f_1$ ,由此就可以进一步推出所有 $f$ 的原值,实现了删除物品。
- # include <cstdio>
- # include <iostream>
- # include <cstring>
- # include <algorithm>
- # define R register int
- using namespace std;
- const int maxn=;
- const int mod=;
- int n,inv_100;
- int m,f[maxn],h[maxn],p[maxn],v[maxn],cnt,ans[maxn],b[maxn];
- struct card { int a,g,p,id; }k[maxn*maxn];
- int qui (int a,int b)
- {
- int s=;
- while(b)
- {
- if(b&) s=1LL*s*a%mod;
- a=1LL*a*a%mod;
- b>>=;
- }
- return s;
- }
- bool cmp (card a,card b) { return a.a>b.a; }
- void ins (int p) { for (R i=n;i>=;--i) f[i]=(1LL*f[i-]*p+1LL*f[i]*(mod+-p))%mod; }
- void del (int p)
- {
- int inv=qui(mod+-p,mod-);
- for (R i=;i<=n;++i)
- {
- f[i]=1LL*f[i]*inv%mod;
- f[i+]=(f[i+]-1LL*p*f[i]%mod+mod)%mod;
- }
- }
- int read()
- {
- int x=;
- char c=getchar();
- while (!isdigit(c)) c=getchar();
- while (isdigit(c)) x=(x<<)+(x<<)+(c^),c=getchar();
- return x;
- }
- int main()
- {
- n=read();
- inv_100=qui(,mod-);
- for (R i=;i<=n;++i)
- {
- m=read();
- for (R j=;j<=m;++j)
- {
- k[++cnt].id=i;
- k[cnt].a=read(),k[cnt].g=read(),k[cnt].p=read();
- p[i]=(p[i]+k[cnt].p)%mod;
- k[cnt].g=1LL*(-k[cnt].g)*inv_100%mod;
- }
- p[i]=qui(p[i],mod-);
- }
- for (R i=;i<=cnt;++i) k[i].p=1LL*k[i].p*p[ k[i].id ]%mod;
- for (R i=;i<=n;++i) v[i]=read();
- sort(k+,k++cnt,cmp);
- f[]=;
- for (R i=;i<=n;++i)
- ins();
- for (R i=;i<=cnt;++i)
- {
- int x=k[i].id;
- del(b[x]);
- for (R j=;j<=n;++j)
- ans[x]=(ans[x]+1LL*k[i].p*k[i].g%mod*f[j]%mod*v[j])%mod;
- b[x]=(b[x]+k[i].p)%mod;
- ins(b[x]);
- }
- for (R i=;i<=n;++i) printf("%d\n",ans[i]);
- return ;
- }
抽卡大赛
B.异或约数和:http://www.51nod.com/Challenge/Problem.html#!#problemId=1984
这题比较简单。
首先看看每个数会被算多少次,显然是 $\frac{n}{i}$ 次,如果这个数是个奇数,它就会出现在最终答案中,否则就不用管它了。
这种分式形式显然上来先套一个除法分块。考虑如何快速计算 $1$ 到 $n$ 的异或和。可以发现 1^2^3=0,(4n)^(4n+1)^(4n+2)^(4n+3)=0,所以就根据 $n \% 4$ 分类讨论即可。
- # include <cstdio>
- # include <iostream>
- # include <cstring>
- # include <string>
- # include <cmath>
- # include <algorithm>
- # define ll long long
- # define R register int
- using namespace std;
- ll n,ans;
- inline ll ask (ll l)
- {
- if(l%==) return l;
- if(l%==) return ;
- if(l%==) return l+;
- return ;
- }
- int main()
- {
- scanf("%lld",&n);
- ll l=,r;
- while(l<=n)
- {
- r=n/(n/l);
- if((n/l)%) ans^=ask(r)^ask(l-);
- l=r+;
- }
- printf("%lld",ans);
- return ;
- }
异或约数和
C.小朋友的笑话:http://www.51nod.com/Challenge/Problem.html#!#problemId=2014
每个人的状态可以认为只与最后听的那个笑话有关。
这里有一个极其神奇(也有可能只是我没见过)的做法:将每个笑话的出现过的区间...维护出来!因为一开始只想到用权值线段树维护区间,但是觉得复杂度不对就弃疗了,其实换成平衡树复杂度就对了。为什么呢?觉得复杂度不对的主要原因就是觉得一种笑话的区间可能很多,如果多次全部访问就会很慢,但其实这个问题是不存在的。如果两个区间出现了重叠,那么我们就把它们删掉,合成一个新的区间再加进去。每次最多加入一个区间,却可能删掉多个,且每个区间被加入后最多被访问一次就被删了,所以复杂度极其科学。
因为Set用的很不熟练,代码几乎是照搬这份题解,就不贴了。
---shzr
51nod 省选联测 R2的更多相关文章
- 51nod“省选”模测第二场 C 小朋友的笑话(线段树 set)
题意 题目链接 Sol 直接拿set维护\(li\)连续段.因为set内的区间互不相交,而且每个线段会被至多加入删除一次,所以复杂度是对的. #include<bits/stdc++.h> ...
- 51nod“省选”模测第二场 B 异或约数和(数论分块)
题意 题目链接 Sol 这题是来搞笑的吧.. 考虑一个数的贡献是\(O(\frac{N}{i})\) 直接数论分块. #include<bits/stdc++.h> #define Pai ...
- 51nod"省选"模测 A 树的双直径(树形dp)
题意 题目链接 Sol 比赛结束后才调出来..不多说啥了,就是因为自己菜. 裸的up-down dp,维护一下一个点上下的直径就行,一开始还想了个假的思路写了半天.. 转移都在代码注释里 毒瘤题目卡空 ...
- 51nod P1354 选数字 题解
每日一题 day8 打卡 Analysis 背包+离散化 这题是我们一次模拟赛的T2,结果我的暴力全TLE了. 关键是如果将两个因数的乘积离散化在因数数组中之后等于这个乘积本身,说明a[j]*in离散 ...
- 清北学堂2018DP&图论精讲班 DP部分学习笔记
Day 1 上午 讲的挺基础的--不过还是有些地方不太明白 例1 给定一个数n,求将n划分成若干个正整数的方案数. 例2 数字三角形 例7 最长不下降子序列 以上太过于基础,不做深入讨论 例3 给定一 ...
- csp-s 考前刷题记录
洛谷 P2615 神奇的幻方 洛谷 P2678 跳石头 洛谷 P1226 [模板]快速幂||取余运算 洛谷 P2661 信息传递 LOJ P10147 石子合并 LOJ P10148 能量项链 LOJ ...
- 51Nod 快速傅里叶变换题集选刷
打开51Nod全部问题页面,在右边题目分类中找到快速傅里叶变换,然后按分值排序,就是本文的题目顺序. 1.大数乘法问题 这个……板子就算了吧. 2.美妙的序列问题 长度为n的排列,且满足从中间任意位置 ...
- [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树)
[51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树) 题面 给出一棵N个点的树,Q次询问一点编号在区间[l1,r1]内,另一点编号在区间[l2,r2]内的所有点对距离最大值.\ ...
- 阿里云学生优惠Windows Server 2012 R2安装IIS,ftp等组件,绑定服务器域名,域名解析到服务器,域名备案,以及安装期间错误的解决方案
前言: 这几天终于还是按耐不住买了一个月阿里云的学生优惠.只要是学生,在学信网上注册过,并且支付宝实名认证,就可以用9块9的价格买阿里云的云服务ECS.确实是相当的优惠. 我买的是Windows S ...
随机推荐
- eclipse安装阿里编码规约插件
点击帮助,Install New Software... 地址为https://p3c.alibaba.com/plugin/eclipse/update 然后选择安装, 一路next即可
- Java自动内存管理机制学习(一):Java内存区域与内存溢出异常
备注:本文引用自<深入理解Java虚拟机第二版> 2.1 运行时数据区域 Java虚拟机在执行Java程序的过程中把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创 ...
- 二进制安装 kubernetes 1.12(五) - 运行测试实例
检查集群状态 # 在 master 上 kubectl get node kubectl get cs 注册登录阿里云容器仓库 因国内无法获得 google 的 pause-amd64 镜像,我这里使 ...
- ajaxJson(常用)
function ajaxJson(method, url, data, callback) { var options = { type: method, url: url, dataType: ' ...
- CSS3效果:animate实现点点点loading动画效果(二)
box-shadow实现的打点效果 简介 box-shadow理论上可以生成任意的图形效果,当然也就可以实现点点点的loading效果了. 实现原理 html代码,首先需要写如下html代码以及cla ...
- Spring学习之旅(四)Spring工作原理再探
上篇博文对Spring的工作原理做了个大概的介绍,想看的同学请出门左转.今天详细说几点. (一)Spring IoC容器及其实例化与使用 Spring IoC容器负责Bean的实例化.配置和组装工作有 ...
- Android横竖屏切换的生命周期
1.新建一个Activity,并把各个生命周期打印出来 2.运行Activity,得到如下信息 onCreate--> onStart--> onResume--> 3.按crtl+ ...
- TeamViewer试用期满转免费版本方法
TeamViewer安装完企业版以后,当试用期结束,到期后,无论你卸载.重装了多少次,都无法无法成功安装个人版,从网上搜索来得到的解决办法就是:安装TeamViewer的时候与你的电脑以及网卡地址进行 ...
- 「破解」Xposed强
「破解」Xposed强 Hook Hook Hook! 两张图片,第一张是我的微信截图,第二张是我从微信Hook出的一些类名. 一段代码,Hook这些类名出来的源码. 知道这些我们能干嘛,当然是分析( ...
- Android IPC机制(一)开启多进程
1. 为何要开启多进程 为何开启android应用要开启多进程,主要有以下几点: 单进程所分配的内存不够,需要更多的内存.在早期android系统只为一个单进程的应用分配了16M的可用内存,随着手机的 ...