HZOI20190818模拟25题解
题面:https://www.cnblogs.com/Juve/articles/11372379.html
A:字符串
其实是CATALAN数水题。。。
和网格一毛一样:https://www.cnblogs.com/Juve/p/11222358.html
#include<iostream>
#include<cstdio>
#include<cstring>
#define mod 20100403
#define int long long
using namespace std;
int n,m,ans=0;
int q_pow(int a,int b,int p){
int res=1;
while(b){
if(b&1) res=(res*a)%p;
a=(a*a)%p;
b>>=1;
}
return res%p;
}
int fac(int n){
if(n==1||n==0) return 1;
int res=1;
for(int i=2;i<=n;i++)
res=(res*i)%mod;
return res%mod;
}
int inv(int n){
if(n==0) return 1;
return q_pow(fac(n),mod-2,mod)%mod;
}
int C(int n,int m){
if(n==m) return 1;
if(n<m) return 0;
return fac(n)*inv(m)%mod*inv(n-m)%mod;
}
signed main(){
scanf("%lld%lld",&n,&m);
ans=C(n+m,n)*q_pow(m+1,mod-2,mod)%mod*(n-m+1)%mod;
printf("%lld\n",ans%mod);
return 0;
}
B:乌鸦坐飞机喝水
乌鸦喝水是“能喝的时候一定喝”的,所以和DP决策没关系。
直接模拟的复杂度为O(nm)
把每个水缸按照可以喝水的次数(即喝多少次水,水位下降到喝不到)由小到大排序,依次处理。
显然如果前面的水缸能喝n次,后面的水缸至少也能喝n次,这个性质十分有用。
由上面这句话可以推出:如果乌鸦从当前位置飞到队伍末会经过k个能喝的水缸,而当前水缸还能喝的次数x>=k,那么之后的水缸也不会在这一轮被喝空。
1、枚举每一个水缸开始(在枚举到该水缸的时候,前面剩余次数更小的水缸已经被喝完。或者可以理解为,舍弃前面的缸,贪心喝这个。)
2、用树状数组维护水缸的ID,查询从当前水缸的ID到(原先的)第n个水缸还有多少个能喝的水缸,如果当前缸的剩余次数>=剩余缸数,直接更新次数并跳到下一轮。
3、在数次2操作后,当前缸的剩余次数<=剩余缸数,此时在树状数组上二分“余数”,即喝到又一轮的某位置时,当前缸没水了。
4、将当前缸标为空,枚举下一个水缸。
表面看着复杂度高,实际上喝水的次数不会超过最多的那个缸能喝的次数(因为每次喝水都是所有缸水位一起下降的),同时,模拟操作的次数不会超过m(最多喝m轮),复杂度可以接受。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define int long long
#define MAXN 100005
using namespace std;
int n,m,x;
struct node{
int d,a,id,tim;
friend bool operator < (node a,node b){
return a.tim<b.tim;
}
}w[MAXN];
struct BITREE{
int c[MAXN];
int lowbit(int x){
return x&(-x);
}
void update(int pos,int val){
for(int i=pos;i<=n;i+=lowbit(i))
c[i]+=val;
}
int query(int pos){
int res=0;
for(int i=pos;i;i-=lowbit(i))
res+=c[i];
return res;
}
}BIT;
int last=0,now=0,ans=0;
int find(int x){
int res=last,l=last,r=n;
while(l<=r){
int mid=(l+r)>>1;
if(BIT.query(mid)-BIT.query(last)<=x)
res=mid,l=mid+1;
else r=mid-1;
}
return res;
}
signed main(){
scanf("%lld%lld%lld",&n,&m,&x);
for(int i=1;i<=n;i++){
scanf("%lld",&w[i].d);
w[i].id=i;
}
for(int i=1;i<=n;i++){
scanf("%lld",&w[i].a);
w[i].tim=(x-w[i].d)/w[i].a+1;
BIT.update(w[i].id,1);
}
sort(w+1,w+n+1);
for(int i=1;i<=n;i++){
if(w[i].tim<ans){
BIT.update(w[i].id,-1);
continue;
}
while(now<m){
int sum=BIT.query(n)-BIT.query(last);
if(sum+ans>w[i].tim) break;
ans+=sum;
last=0;
now++;
}
if(now>=m) break;
last=find(w[i].tim-ans);
ans=w[i].tim;
BIT.update(w[i].id,-1);
}
printf("%lld\n",ans);
return 0;
}
C:所驼门王的宝藏
%%AlpaCa羊驼哥
题面挺吓人,但是水题一个
首先你要从提干中的输入建出图来
建图非常sb
我定义了两个vector,存每行每列的宫殿坐标及类型
然后扫描每行,搜到一个横天门就把它和这一行每一个宫殿连边,其他同理,
然后就和之前的爆炸行动一样了,
tarjan缩点,然后在新建的图上跑拓扑,找到新图上的最长链
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#define MAXK 1000005
#define re register
using namespace std;
int n,m,k,ans=0,res[MAXK];
struct node{
int opt,id,x,y;
};
vector<node>h[MAXK],l[MAXK];
struct EDGE{
int to,nxt;
}e[MAXK<<2];
int head[MAXK],cnt=0;
inline void add(re int u,re int v){
cnt++,e[cnt].to=v,e[cnt].nxt=head[u],head[u]=cnt;
}
int dfn[MAXK],low[MAXK],sta[MAXK],top=0,dfs_order=0,tot=0,belong[MAXK],siz[MAXK];
bool in_sta[MAXK];
inline void tarjan(re int x){
dfn[x]=low[x]=++dfs_order;
sta[++top]=x;
in_sta[x]=1;
for(re int i=head[x];i;i=e[i].nxt){
re int y=e[i].to;
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(in_sta[y]) low[x]=min(low[x],dfn[y]);
}
if(dfn[x]==low[x]){
tot++;
re int y;
do{
y=sta[top--];
in_sta[y]=0;
belong[y]=tot;
siz[tot]++;
}while(y!=x);
}
}
int to[MAXK<<2],nxt[MAXK<<2],pre[MAXK],sum=0;
inline void ADD(re int u,re int v){
sum++,to[sum]=v,nxt[sum]=pre[u],pre[u]=sum;
}
int in_deg[MAXK];
queue<int>q;
int main(){
scanf("%d%d%d",&k,&n,&m);
for(re int i=1,u,v,opt;i<=k;i++){
scanf("%d%d%d",&u,&v,&opt);
h[u].push_back((node){opt,i,u,v});
l[v].push_back((node){opt,i,u,v});
}
for(re int i=1;i<=n;i++){
re int N=h[i].size();
for(re int j=0;j<N;j++){
node t=h[i][j];
if(t.opt==1){
for(re int p=0;p<N;p++){
if(t.id==h[i][p].id) continue;
add(t.id,h[i][p].id);
}
}else if(t.opt==2){
re int M=l[t.y].size();
for(re int p=0;p<M;p++){
if(t.id==l[t.y][p].id) continue;
add(t.id,l[t.y][p].id);
}
}else{
for(re int p=max(1,t.x-1);p<=min(n,t.x+1);p++){
re int r=h[p].size();
for(re int q=0;q<r;q++){
if(h[p][q].id==t.id) continue;
if(abs(t.y-h[p][q].y)>1) continue;
add(t.id,h[p][q].id);
}
}
}
}
}
for(re int i=1;i<=k;i++){
if(!dfn[i]) tarjan(i);
}
for(re int i=1;i<=k;i++){
for(re int j=head[i];j;j=e[j].nxt){
re int y=e[j].to;
if(belong[y]!=belong[i]){
ADD(belong[i],belong[y]);
in_deg[belong[y]]++;
}
}
}
for(re int i=1;i<=tot;i++){
res[i]=siz[i];
if(!in_deg[i]) q.push(i);
}
while(!q.empty()){
re int x=q.front();
q.pop();
in_deg[x]--;
for(re int i=pre[x];i;i=nxt[i]){
re int y=to[i];
in_deg[y]--;
res[y]=max(res[y],res[x]+siz[y]);
ans=max(res[y],ans);
if(!in_deg[y]) q.push(y);
}
}
//for(re int i=1;i<=tot;i++)
// ans=max(res[i],ans);
printf("%d\n",ans);
return 0;
}
HZOI20190818模拟25题解的更多相关文章
- [NOIP模拟25]题解
A.字符串 Catalan数不能再裸了 #include<cstdio> #include<iostream> #include<cstring> using na ...
- [CQOI2012]模拟工厂 题解(搜索+贪心)
[CQOI2012]模拟工厂 题解(搜索+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327574 链接题目地址:洛谷P3161 BZOJ P26 ...
- NOIP第7场模拟赛题解
NOIP模拟赛第7场题解: 题解见:http://www.cqoi.net:2012/JudgeOnline/problemset.php?page=13 题号为2221-2224. 1.car 边界 ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- HGOI NOIP模拟4 题解
NOIP国庆模拟赛Day5 题解 T1 马里奥 题目描述 马里奥将要参加 NOIP 了,他现在在一片大陆上,这个大陆上有着许多浮空岛,并且其中一座浮空岛上有一个传送门,马里奥想要到达传送门从而前往 N ...
- 10.8 wtx模拟题题解
填坑 orz w_x_c_q w_x_c_q的模拟赛(150pts,炸了) money 题目背景: 王小呆又陷入自己的梦里.(活在梦里...) 题目描述: 王小呆是一个有梦想的小菜鸡,那就是赚好多好多 ...
- [NOIP模拟13]题解
A.矩阵游戏 其实挺水的? 考场上根本没有管出题人的疯狂暗示(诶这出题人有毛病吧这么简单的东西写一大堆柿子),而且推公式能力近乎没有,所以死掉了. 很显然乘法有交换率结合率所以操作顺序对最终结果没什么 ...
- 「题解」NOIP模拟测试题解乱写II(36)
毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...
- ZOJ 3430 Detect the Virus(AC自动机 + 模拟)题解
题意:问你主串有几种模式串.但是所有串都是加密的,先解码.解码过程为:先把串按照他给的映射表变成6位数二进制数,然后首尾衔接变成二进制长串,再8位8位取变成新的数,不够的补0.因为最多可能到255,所 ...
随机推荐
- thinkphp 切换数据库
除了在预先定义数据库连接和实例化的时候指定数据库连接外,我们还可以在模型操作过程中动态的切换数据库,支持切换到相同和不同的数据库类型.用法很简单, 只需要调用Model类的db方法,用法: 常州大理石 ...
- 0925CSP-S模拟测试赛后总结
献上了自己的第二次爆零. 最近考试持续低迷.受同桌影响是一方面,自己的状态不行也是一方面,根本还是实力不行. 昨天T1是签到题.然而并没有发现这个事实.并不会打…… 无意围观同桌秒切T1,秒过样例,长 ...
- Vue+Iview+Node 安装环境 运行测试Vue
1.运行环境及设置 备注:建议设置 npm config set registry https://registry.npm.taobao.org 2.全局安装vue/cli 3.创建vue 项目 v ...
- C++Builder中注册表的操作
僮骶头浅5募虻チ耍旅嫖揖鸵砸桓鍪道此得鱐Registry类的用法.首先,先介绍一下TRegistry的属性和方法:TRegistry类一共有四个属性.属性 类型 描述CurrentKey int ...
- py测试一个Socket实例
本实例旨在了解py和socket的一些相关知识. 1.服务器端搭建py监听程序. 在客户端搭建python,linux默认自带了python2.7,先不管安装了. 接着编写socket程序,可以在本地 ...
- jquery学习笔记(一):选择器
内容来自[汇智网]jquery学习课程 1.1 基础选择器 选择器 功能 返回值 #id 根据给定的id匹配一个元素 单个元素 element 根据给定的元素名匹配所有元素 元素集合 .class 根 ...
- P1977 出租车拼车
P1977 出租车拼车 题目背景 话说小 x 有一次去参加比赛,虽然学校离比赛地点不太远,但小 x 还是想坐 出租车去.大学城的出租车总是比较另类,有“拼车”一说,也就是说,你一个人 坐车去,还是一堆 ...
- hdu-4893
http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意: 给定一个数组a,一开始数组里面的元素都是0,现在有三个操作: 操作1:给第k个数字加上d. 操作2 ...
- Spring - JUnit整合测试
1.导包:test.jar - (依赖 aop.jar) 2.使用@RunWith注解创建spring容器 - @RunWith(SpringJUnit4ClassRunner.class) 3.使用 ...
- Java基础 ----- 判断对象的类型
1. 判断对象的类型:instanceOf 和 isInstance 或者直接将对象强转给任意一个类型,如果转换成功,则可以确定,如果不成功,在异常提示中可以确定类型 public static vo ...