T1 字符串

卡特兰数

设1为向(1,1)走,0为向(1,-1)走,限制就是不能超过$y=0$这条线,题意转化为从(0,0)出发,走到(n+m,n-m)且不越过$y=0$,然后就裸的卡特兰数,$ans=C(n+m,n)-C(n+m,m-1)$

#include<iostream>
#include<cstdio>
#include<cstring>
#define mod 20100403
#define ll long long
using namespace std;
ll n,m,inv[],fac[],facinv[];
ll read()
{
ll aa=,bb=;char cc=getchar();
while(cc>''||cc<''){if(cc=='-') bb=-;cc=getchar();}
while(cc<=''&&cc>=''){aa=(aa<<)+(aa<<)+(cc^'');cc=getchar();}
return aa*bb;
}
ll C(ll x,ll y)
{
return fac[x]*facinv[x-y]%mod*facinv[y]%mod;
}
int main()
{
n=read();m=read();
fac[]=;facinv[]=;inv[]=;
for(ll i=;i<=n+m;i++){
if(i!=) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
fac[i]=fac[i-]*i%mod;
facinv[i]=facinv[i-]%mod*inv[i]%mod;
}
printf("%lld\n",(C(n+m,n)-C(n+m,m-)+mod)%mod);
return ;
}

字符串

T2 乌鸦喝水

两条性质:

1.若水少的喝了$x$次,那么比他水多的至少喝了$x$次。所以按能喝的次数升序排列。

2.排序后的序列里,当前水缸还能喝的次数${\ge}k$,那么之后的水缸在这一轮也不会被喝完。

于是我们在排完序的序列里,每次找到最少的,看他能喝几轮,直接跳,所以用树状数组维护当前点的实际坐标的右边还可以喝$k$次,若$num>k+ans$那就飞一轮,同时更新答案,若$num<k+ans$,就在原序列上二分看他最多跳到哪(记得更新答案),同时把排序后的序列的下标向右推一位,因为这一位已经失效了。

树状数组的具体实现就是以原坐标为下标,插入每个点是否存在,存在为1,不存在为0,维护前缀和,查询的时候直接减就可以得到右边有多少个点。

#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
struct node
{
int id,cnt;
}h[];
ll n,m,x,w[],a[],c[],ans,cir;
ll read()
{
ll aa=,bb=;char cc=getchar();
while(cc>''||cc<''){if(cc=='-') bb=-;cc=getchar();}
while(cc<=''&&cc>=''){aa=(aa<<)+(aa<<)+(cc^'');cc=getchar();}
return aa*bb;
}
bool cmp(node a,node b)
{
return a.cnt==b.cnt?a.id<b.id:a.cnt<b.cnt;
}
int lowbit(int x)
{
return x&(-x);
}
void insert(int x,int w)
{
while(x<=n){
c[x]+=w;
x+=lowbit(x);
}
}
int query(int x)
{
int as=;
while(x){
as+=c[x];
x-=lowbit(x);
}
return as;
}
int main()
{
n=read();m=read();x=read();
for(int i=;i<=n;i++) w[i]=read();
for(int i=,u;i<=n;i++){
u=read();
h[i].id=i;
h[i].cnt=(x-w[i])/u+;
insert(i,);
}
sort(h+,h+n+,cmp);
int pos=,las=;//pos排序后的序列 las原序列
for(int pos=;pos<=n;pos++){
while(cir<m&&query(n)-query(las-)+ans<h[pos].cnt){
cir++;
ans+=query(n)-query(las-);
las=;
}
if(cir>=m) break;
int l=las,r=n,as=las-;
while(l<=r){
int mid=(l+r)>>;
if(query(mid)-query(las-)+ans<=h[pos].cnt){
as=mid;
l=mid+;
}
else r=mid-;
}
ans+=query(as)-query(las-);
las=(as==n)?:as+;
if(as==n) cir++;
insert(h[pos].id,-);
}
printf("%lld\n",ans);
return ;
}

乌鸦喝水

T3 所驼门王的宝藏

考场看错题,周围8个点理解成向左右上下个拓展8个点,嘤嘤嘤

把每个传送门能去的有宝藏的地方建单向边,tarjan缩点,重新建边,topu找最长链。(因为是单向边,dfs是($n^2$)的,时间受不住,topu只需要($n$))

最恶心的是建边,用$vector$ 存每一行 每一列都有哪些宝藏(用于$opt==1||opt==2$),用$map$映射二元组记录每个点的位置(用于$opt==3$),然后直接建就行

#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<queue>
using namespace std;
struct node
{
int to,nxt;
}h[],hh[];
struct nnde
{
int x,y,opt;
}t[];
int ans;
int n,r,c,tot,nxt[],opt[],tx[]={,,-,-,-,,,},ty[]={-,,-,,,-,,};
int nx[],tet,d[],val[];
int dfn[],low[],s[],top,whos[],cnt,num,shu[];
bool is[],vis[],v[];
vector<int>hang[],lie[],ve;
map< pair<int,int> ,int>mp;
int read()
{
int aa=,bb=;char cc=getchar();
while(cc>''||cc<''){if(cc=='-') bb=-;cc=getchar();}
while(cc<=''&&cc>=''){aa=(aa<<)+(aa<<)+(cc^'');cc=getchar();}
return aa*bb;
}
void add(int x,int y)
{
h[++tot].to=y;
h[tot].nxt=nxt[x];
nxt[x]=tot;
}
void ad(int x,int y)
{
hh[++tet].to=y;
hh[tet].nxt=nx[x];
nx[x]=tet;
}
void tarjan(int x)
{
dfn[x]=low[x]=++cnt;
s[++top]=x;is[x]=;
for(int i=nxt[x];i;i=h[i].nxt){
int y=h[i].to;
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(is[y]) low[x]=min(low[x],dfn[y]);
}
if(dfn[x]==low[x]){
num++;
while(){
int tmp=s[top--];
whos[tmp]=num;
shu[num]++;
is[tmp]=;
if(tmp==x) break;
}
}
}
void topu()
{
queue<int>q;
for(int i=;i<=num;i++){
if(!d[i]) q.push(i),val[i]=shu[i],ans=max(ans,val[i]);
}
while(q.size()){
int x=q.front();q.pop();
for(int i=nx[x];i;i=hh[i].nxt){
int y=hh[i].to;
d[y]--;
val[y]=max(val[y],val[x]+shu[y]);
ans=max(ans,val[y]);
if(!d[y]) q.push(y);
}
}
}
int main()
{
n=read();r=read();c=read();
int x,y,opt;
for(int i=;i<=n;i++){
t[i].x=read();t[i].y=read();t[i].opt=read();
hang[t[i].x].push_back(i);
lie[t[i].y].push_back(i);
mp[make_pair(t[i].x,t[i].y)]=i;
}
for(int i=;i<=n;i++){
int x=t[i].x,y=t[i].y,opt=t[i].opt;
if(opt==){
for(int j=;j<hang[x].size();j++){
if(i==hang[x][j]) continue;
add(i,hang[x][j]);
}
}
else if(opt==){
for(int j=;j<lie[y].size();j++){
if(i==lie[y][j]) continue;
add(i,lie[y][j]);
}
}
else if(opt==){
for(int j=;j<;j++){
if(mp[make_pair(x+tx[j],y+ty[j])]){
add(i,mp[make_pair(x+tx[j],y+ty[j])]);
}
}
}
}
for(int i=;i<=n;i++) if(!dfn[i]) tarjan(i);
for(int i=;i<=n;i++){
ve.clear();
for(int j=nxt[i];j;j=h[j].nxt){
int y=h[j].to;
if(whos[y]!=whos[i]&&!vis[whos[y]]){
ad(whos[i],whos[y]);
d[whos[y]]++;
ve.push_back(whos[y]);
vis[whos[y]]=;
}
}
for(int j=;j<ve.size();j++) vis[ve[j]]=;
}
topu();
printf("%d\n",ans);
return ;
}

所驼门王的宝藏

8.18 NOIP模拟测试25(B) 字符串+乌鸦喝水+所驼门王的宝藏的更多相关文章

  1. NOIP模拟测试25「字符串·乌鸦喝水·所陀门王的宝藏(陀螺王)」

    字符串 题解 没看出catalan怎么办 dp打表啊! 考虑大力dp拿到30分好成绩!顺便收获一张表 打表发现$C_{n+m}^{m}-C_{n+m}^{m-1}$ 仔细观察然后发现其实就是之前的网格 ...

  2. 「模拟8.18」字符串(卡特兰数)·乌鸦喝水(树状数组,二分)·所驼门王的宝藏(tarjan,拓扑)

    最近好颓啊,所以啥都做不出来 简单说一下这次考试,分机房了,还分不同考卷,果然我还是留在二机房的蒟蒻, 大概也只有这样的简单题,才能勉强水个rank 3吧........ 其实不必管在哪个机房,努力便 ...

  3. NOIP模拟测试2-5

    该补一下以前挖的坑了 先总结一下 第二次 T1 搜索+剪枝 #include<cstdio> #include<iostream> #define ll long long u ...

  4. NOIP模拟测试25

    这次考试后面心态爆炸了...发现刚了2h的T2是假的之后就扔掉了,草率地打了个骗分 T1只会搜索和m=0 最先做的T3,主要是发现部分分很多,当时第一眼看上去有87分(眼瞎了). 后来想了想,感觉一条 ...

  5. 7.18 NOIP模拟测试5 星际旅行+砍树+超级树

    T1 星际旅行 题意:n个点,m条边,无重边,有自环,要求经过m-2条边两次,2条边一次,问共有多少种本质不同的方案.本质不同:当且仅当至少存在一条边经过次数不同. 题解:考试的时候理解错题,以为他是 ...

  6. noip模拟5[string·matrix·big·所驼门王的宝藏]

    怎么说呢这一场考得还算可以呢 拿了120pts,主要是最后一个题灵光开窍,想起来是tarjan,然后勉勉强强拿了40pts,本来是可以拿满分的,害 没事考完了就要反思 这场考试我心态超好,从第一个题开 ...

  7. NOIP模拟测试17&18

    NOIP模拟测试17&18 17-T1 给定一个序列,选取其中一个闭区间,使得其中每个元素可以在重新排列后成为一个等比数列的子序列,问区间最长是? 特判比值为1的情况,预处理比值2~1000的 ...

  8. 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组

    2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...

  9. 「题解」NOIP模拟测试题解乱写II(36)

    毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...

随机推荐

  1. c#菜单动态合并 z

    说明 在程序中经常使用弹出菜单,并且一个窗体中可以存在多个弹出菜单.开发过MDI窗体的读者可能都知道,当MDI子窗体最大化时,子窗体和主窗体的菜单能够自动的合并.这是如何实现的呢?本例实现了将两个弹出 ...

  2. python-10-列表、元组嵌套

    前言 元组.列表前面章节有讲解实例,本节内容是列表.元组的多嵌套. 一.列表嵌套 1.列表嵌套操作1 # 列表的嵌套 li = ['xiaolong', '小林', ['小龙', 'xiaol'], ...

  3. LeetCode 225:用队列实现栈 Implement Stack using Queues

    题目: 使用队列实现栈的下列操作: push(x) -- 元素 x 入栈 pop() -- 移除栈顶元素 top() -- 获取栈顶元素 empty() -- 返回栈是否为空 Implement th ...

  4. MongoDB自学------(2)创建删除数据库及集合

    一.创建数据库 二.查看所有数据库 三.删除数据库 四.创建集合 五.删除集合 六.集合用法介绍 1.创建集合 2.删除集合 下一篇链接:https://www.cnblogs.com/LinHuCh ...

  5. background属性怎么添加2个或多个背景图

    最近遇到一个需求,下面充值金额按钮是一个背景图,点击之后显示的状态也是一个背景图,如下图      按照惯用的套路,新增一个class,点击后的状态直接写在里面即可 然而点击后,虽然状态背景成功显示出 ...

  6. asp.net mvc4 bundle添加带min的js问题

    今天在用ScriptBundle的时候发现js文件有min的,无法bundle进去,具体我也不知道怎么回事. @Tony Tan 回复:bundles.IgnoreList可以设置 去除min.js的 ...

  7. MyBatis面试题集合,90%会遇到这些问题

    1.#{}和${}的区别是什么? ${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc. ...

  8. @property与@xxx.setter的用法

    类中@property与@xxx.setter的方法介绍. 简单说,@property就是将定义的函数(方法)当作属性对象使用,不需要像调用函数那样去调用,而@xxx.setter是为@xxx的这样函 ...

  9. win10笔记本电脑连wifi显示“无internet,安全”解决办法

    吹一波, 不出意外的话,这应该是网上最全最详细的解决办法......毕竟妹子的电脑遇到了问题,咱一定要给她解决啊. 问题描述:连上了WiFi,显示“无Internet,安全”.但实际上她的电脑是有网的 ...

  10. [b0012] Hadoop 版hello word mapreduce wordcount 运行(二)

    目的: 学习Hadoop mapreduce 开发环境eclipse windows下的搭建 环境: Winows 7 64 eclipse 直接连接hadoop运行的环境已经搭建好,结果输出到ecl ...