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. vscode10个必装的插件

    VSCode 必装的 10 个高效开发插件   本文介绍了目前前端开发最受欢迎的开发工具 VSCode 必装的 10 个开发插件,用于大大提高软件开发的效率. VSCode 的基本使用可以参考我的原创 ...

  2. git操作记录(如何回退到某个历史版本,如何提交部分文件等方法)

    当前项目使用git管理代码,在使用的过程中会遇到一些问题,这里记录下 1.合并代码后 在合并组员的代码后会出现下面的界面,开始的时候都会关闭,重新打开,乐此不疲到忍无可忍 解决方法: 出现这种界面是要 ...

  3. undefined reference的一种case

    undefined reference是经常遇到的链接错误,一般是函数未定义或未正确链接引起的问题: but 有一种case,比较坑... c++ 调用 c 的函数,当c函数未加:extern “C” ...

  4. tf.ConfigProto()

    tf.ConfigProto一般用在创建session的时候用来对session进行参数配置 with tf.Session(config=tf.ConfigProto(...)...) tf.Con ...

  5. Springboot2 Metrics之actuator集成influxdb, Grafana提供监控和报警

    到目前为止,各种日志收集,统计监控开源组件数不胜数,即便如此还是会有很多人只是tail -f查看一下日志文件.随着容器化技术的成熟,日志和metrics度量统计已经不能仅仅靠tail -f来查看了,你 ...

  6. ASP.NET web.config 配置里部分参数详细说明

    Session配置 <!-- <identity impersonate = "false" [true|false] userName = "" ...

  7. express捕获全局异常的三种方法

    场景 express的路由里抛出异常后,全局中间件没办法捕获,需要在所有的路由函数里写try catch,这坑爹的逻辑让人每次都要多写n行代码 官方错误捕获中件间代码如下 app.use(functi ...

  8. 2.将视图添加到 ASP.NET Core MVC 应用

    在本部分中,将修改 HelloWorldController 类,进而使用 Razor 视图文件来顺利封装为客户端生成 HTML 响应的过程. 当前,Index 方法返回带有在控制器类中硬编码的消息的 ...

  9. MySQL基础(三)(操作数据表中的记录)

    1.插入记录INSERT 命令:,expr:表达式 注意:如果给主键(自动编号的字段)赋值的话,可以赋值‘NULL’或‘DEFAULT’,主键的值仍会遵守默认的规则:如果省略列名的话,所有的字段必须一 ...

  10. grep日志去重

    grep --text ' ERROR '2017.06.08.log | grep '12345678' | grep -Eo 'telephone=.*{11},p'| sort | uniq | ...