菜鸡wwb因为想不出口胡题所以来写题解了

A. chess


昨天晚上考试,有点困

开考先花五分钟扫了一边题,好开始肝$T1$

看了一眼$m$的范围很大,第一反应矩阵快速幂??

$n$很小,那么可以打$n^4$的DP,

$10min$过去了,好像就是一个$DP$啊,随便乘个组合数就好了,

最后距离考试$20min$时,因为瞎取模,把自己的$AC$覆盖了kukukuku

正解的话,首先对于第一列而言,第$1+n$列的放的$C$的个数与他相同

但是因为只知道数目我们乘上组合数就好

$f_{ij}$表示第$i$行,一共放了$j$个棋子的方案数,转移即可

思路积累:

1。快速幂要预处理

2。指数不能取模

3。观察数据范围合理进行递推

B. array


觉得题还是不错的考场想了半个小时想到的

题意:

给出一个序列,每个数有一个权值,求满足$a_{k}\leq a_{j}\leq a_{i}(k\leq j\leq i)$中$k$的最小值

我的做法是维护两个单调栈,一个单调递增,一个单调递减

假设当前单减的栈的只栈顶是$maxtop$,递减的是$mintop$;

对于单减的栈当我们插入$i$后,$st_{maxtop-1}$是左边第一个大于$i$的节点,

所以我们已经满足了第一个条件,

对于第二个条件因为在单增栈中对于任意节点$k$,从它到栈顶的所有值都大于它

因此我们通过$st_{maxtop-1}$直接在单增栈中$upperbound$即可

当然这是考场瞎打水过的,并不是正解。

事实上不用维护第二个栈只需要在每次弹递增栈时记录一个数组$pos_{j}$表示从$j$开始到左侧第一比他大的元素中

权值最小的元素位置,没一段$pos_{j}$都控制一段区域,可以在弹栈中维护。

思路积累:

1.对于区间具有单调性的问题可以考虑单调栈

2.单减的栈保证栈中每个元素到栈首的值都小于等于该元素

单增保证每个元素到栈首的值都大于等于该元素

C. ants


听说是原题,我又没做过......

$50$算法

莫队+线段树,维护区间最长连续区间和

$100$算法

回滚莫队+并查集

第一次接触回滚莫队,莫队大法吼....

简单叙述一下

对于一些问题我们发现对于区间的移动而言加\减的操作很难维护,那么为了比较好的时间复杂度,可以采用回滚莫队

对于该题,他的删数操作我们很难维护区间最大子段和,那么我们开始思考我们令操作中只有加操作即可

那么我们采用分块思想,区间左端点所在块为第一关键字,右端点为第二关键字

 bool cmp(no a,no b){return (bel[a.l]==bel[b.l])?(a.r<b.r):(a.l<b.l);} 

然后我们选一个块,发现我们先处理出$L-r_{x}$的部分,

也就是说处理出左端点到他所在的块的最右端,然后我们发现对于右端点是单调的

那么我们保持右端点的贡献不清空,每次清空左段点到块的那部分

当然假如两端点在同一块内就直接暴力处理

至于并查集

采用按秩合并思想,然后我们用一个栈记录以前的相连的点,相当与是时间戳一样

然后每次回溯撤销

注意对于右边区间我们要继承上一状态

#include<bits/stdc++.h>
#define int long long
#define MAXN 1100000
using namespace std;
int read(){
char c=getchar();int x=0;
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x;
}
int deep[MAXN],fa[MAXN];int n,m;int a[MAXN];
struct node{
int fa,to;
void insert(int x,int y){fa=x;to=y;}
}T[MAXN];int top=0;
void del(){
while(top){
fa[T[top].to]=T[top].to;
deep[T[top].fa]-=deep[T[top].to];
top--;
}
}
int ans[MAXN];int bel[MAXN];int kuan;int l[MAXN],r[MAXN];
struct no{int l,r,id;}e[MAXN];
int find(int x){
if(fa[x]==0)return 0;
if(fa[x]==x)return x;
return find(fa[x]);
}
bool cmp(no a,no b){return (bel[a.l]==bel[b.l])?(a.r<b.r):(a.l<b.l);}
void init(){
memset(l,0x3f3f3f,sizeof(l));
kuan=sqrt(n);
for(int i=1;i<=n;++i){
int me=(i-1)/kuan+1;
bel[i]=me;
l[me]=min(i,l[me]);
r[me]=max(i,r[me]);
}
}
vector<int>v[MAXN];
int merge(int x,int y,int opt){
if(deep[x]>=deep[y]){
deep[x]+=deep[y];
fa[y]=x;
if(opt)T[++top].insert(x,y);
return deep[x];
}
else{
deep[y]+=deep[x];
fa[x]=y;
if(opt)T[++top].insert(y,x);
return deep[y];
}
}
void work(int x){
int R=r[x];//printf("x=%lld\n",x);
int rs=0;
for(int k=0;k<v[x].size();++k){
int to=v[x][k];
int ll=e[to].l;int rr=e[to].r;
//printf("ll=%lld rr=%lld be=%lld ber=%lld\n",ll,rr,bel[ll],bel[rr]);
if(bel[ll]==bel[rr]){
int maxn=0;
for(int i=ll;i<=rr;++i){
fa[a[i]]=a[i];deep[a[i]]=1;maxn=max(deep[a[i]],maxn);
int fa1=find(a[i]-1);
if(fa1){maxn=max(merge(fa1,a[i],1),maxn);}
int fa2=find(a[i]+1);int me=find(a[i]);
if(fa2){maxn=max(merge(fa2,me,1),maxn);}
}
ans[e[to].id]=maxn;
del();
for(int i=ll;i<=rr;++i)fa[a[i]]=0,deep[a[i]]=0;
}
else{
int maxn=0;
for(int i=R+1;i<=rr;++i){
//printf("work2 a[%lld]=%lld\n",i,a[i]);
fa[a[i]]=a[i];deep[a[i]]=1;maxn=max(deep[a[i]],maxn);
int fa1=find(a[i]-1);
if(fa1){maxn=max(merge(fa1,a[i],0),maxn);rs=max(maxn,rs);}
int fa2=find(a[i]+1);int me=find(a[i]);
if(fa2){maxn=max(merge(fa2,me,0),maxn);rs=max(maxn,rs);}
}
for(int i=ll;i<=r[x];++i){
//printf("work1 a[%lld]=%lld\n",i,a[i]);
fa[a[i]]=a[i];deep[a[i]]=1;maxn=max(deep[a[i]],maxn);
int fa1=find(a[i]-1);
if(fa1){maxn=max(merge(fa1,a[i],1),maxn);}
int fa2=find(a[i]+1);int me=find(a[i]);
if(fa2){maxn=max(merge(fa2,me,1),maxn);}
}
ans[e[to].id]=max(maxn,rs);
del();
R=rr;
for(int i=ll;i<=r[x];++i)fa[a[i]]=0,deep[a[i]]=0;
}
}
for(int i=r[x]+1;i<=R;++i)fa[a[i]]=0,deep[a[i]]=0;
}
signed main(){
//freopen("1.in","r",stdin);
//freopen("w.out","w",stdout);
n=read();m=read();
for(int i=1;i<=n;++i){
a[i]=read();
}
init();
for(int i=1;i<=m;++i){
e[i].l=read();e[i].r=read();e[i].id=i;
}
sort(e+1,e+m+1,cmp);
for(int i=1;i<=m;++i){int to=e[i].l;v[bel[to]].push_back(i);}
for(int i=1;i<=(n-1)/kuan+1;++i){
if(!v[i].size())continue;
work(i);
}
for(int i=1;i<=m;++i){
printf("%lld\n",ans[i]);
}
}

思路积累

1.回滚莫队处理比较难的区间操作

2.查询区间连续子段长度,可以按秩合并并查集

「10.11」chess(DP,组合数学)·array(单调栈)·ants(莫队,并茶几)的更多相关文章

  1. LOJ#3083.「GXOI / GZOI2019」与或和_单调栈_拆位

    #3083. 「GXOI / GZOI2019」与或和 题目大意 给定一个\(N\times N\)的矩阵,求所有子矩阵的\(AND(\&)\)之和.\(OR(|)\)之和. 数据范围 \(1 ...

  2. LOJ#3083. 「GXOI / GZOI2019」与或和(单调栈)

    题面 传送门 题解 按位考虑贡献,如果\(mp[i][j]\)这一位为\(1\)就设为\(1\)否则设为\(0\),对\(or\)的贡献就是全为\(1\)的子矩阵个数,对\(and\)的贡献就是总矩阵 ...

  3. 「洛谷5300」「GXOI/GZOI2019」与或和【单调栈+二进制转化】

    题目链接 [洛谷传送门] 题解 按位处理. 把每一位对应的图都处理出来 然后单调栈处理一下就好了. \(and\)操作处理全\(1\). \(or\)操作处理全\(0\). 代码 #include & ...

  4. 【dp 状态压缩 单调栈】bzoj3591: 最长上升子序列

    奇妙的单调栈状压dp Description 给出1~n的一个排列的一个最长上升子序列,求原排列可能的种类数. Input 第一行一个整数n. 第二行一个整数k,表示最长上升子序列的长度. 第三行k个 ...

  5. 「算法笔记」树形 DP

    一.树形 DP 基础 又是一篇鸽了好久的文章--以下面这道题为例,介绍一下树形 DP 的一般过程. POJ 2342 Anniversary party 题目大意:有一家公司要举行一个聚会,一共有 \ ...

  6. BZOJ5125: [Lydsy1712月赛]小Q的书架【决策单调性优化DP】【BIT】【莫队】【分治】

    小Q有n本书,每本书有一个独一无二的编号,现在它们正零乱地在地上排成了一排. 小Q希望把这一排书分成恰好k段,使得每段至少有一本书,然后把每段按照现在的顺序依次放到k层书架的每一层上去.将所有书都放到 ...

  7. Powerful array CodeForces - 86D (莫队算法)

    An array of positive integers a1, a2, ..., an is given. Let us consider its arbitrary subarray al, a ...

  8. BZOJ.3238.[AHOI2013]差异(后缀自动机 树形DP/后缀数组 单调栈)

    题目链接 \(Description\) \(Solution\) len(Ti)+len(Tj)可以直接算出来,每个小于n的长度会被计算n-1次. \[\sum_{i=1}^n\sum_{j=i+1 ...

  9. Educational Codeforces Round 23 D. Imbalanced Array 单调栈

    D. Imbalanced Array time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

随机推荐

  1. Spring Cloud Alibaba(8)---Feign服务调用

    Feign服务调用 有关Spring Cloud Alibaba之前写过五篇文章,这篇也是在上面项目的基础上进行开发. Spring Cloud Alibaba(1)---入门篇 Spring Clo ...

  2. 腾讯云原生混合云-第三方集群弹EKS应对突发流量的利器

    作者 何鹏飞,腾讯云专家产品经理,曾作为容器私有云.TKEStack的产品经理兼架构师,参与腾讯云内部业务.外部客户容器化改造方案设计,目前负责云原生混合云产品方案设计工作. 胡晓亮,腾讯云专家工程师 ...

  3. 3D高清电商购物小图标图片_在线商城三维icon图标素材大全

    3D高清电商购物小图标图片_在线商城三维icon图标素材大全

  4. jekyll-admin的搭建和使用

    通过jekyll搭建好了自己的博客.写博客成为了日常,经过一段时间的摸索,发现jekyll-admin是个好东西,它是博客的后台管理系统,可以方便的管理和编写自己的博客 安装 运行命令gem inst ...

  5. java基础——Scanner的基础和进阶

    Scanner对象 目的:用来获取用户的输入 基本语法: Scanner s = new scanner (System.in); 通过Scanner 类的next()和nextLine()方法,获取 ...

  6. OpenStack常见面试题

    现在,大多数公司都试图将它们的 IT 基础设施和电信设施迁移到私有云, 如 OpenStack.如果你打算面试 OpenStack 管理员这个岗位,那么下面列出的这些面试问题可能会帮助你通过面试. Q ...

  7. IIC通信时遇到问题的解决

    如果遇到问题,反复查不到 就DEBUG  下单点运行,执行每一个SCK 和SDA的拉高拉低 看看是否能正常的拉高拉低 先解决掉底层的GPIO的控制问题, 有的时候可能数据引脚为特殊功能引脚

  8. Python3.x 基础练习题100例(71-80)

    练习71: 题目: 编写input()和output()函数输入,输出5个学生的数据记录. 程序: N = 5 # stu # num : string # name : string # score ...

  9. ASP.NET Core文件上传IFormFile于Request.Body的羁绊

    前言 在上篇文章深入探究ASP.NET Core读取Request.Body的正确方式中我们探讨了很多人在日常开发中经常遇到的也是最基础的问题,那就是关于Request.Body的读取方式问题,看是简 ...

  10. fragment之间相互传数据、共享数据

    在 Fragment 之间共享数据 Activity 中的两个或更多 Fragment 需要相互通信是一种很常见的现象.想象一下拆分视图 (master-detail) Fragment 的常见情况, ...