「10.11」chess(DP,组合数学)·array(单调栈)·ants(莫队,并茶几)
菜鸡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(莫队,并茶几)的更多相关文章
- LOJ#3083.「GXOI / GZOI2019」与或和_单调栈_拆位
#3083. 「GXOI / GZOI2019」与或和 题目大意 给定一个\(N\times N\)的矩阵,求所有子矩阵的\(AND(\&)\)之和.\(OR(|)\)之和. 数据范围 \(1 ...
- LOJ#3083. 「GXOI / GZOI2019」与或和(单调栈)
题面 传送门 题解 按位考虑贡献,如果\(mp[i][j]\)这一位为\(1\)就设为\(1\)否则设为\(0\),对\(or\)的贡献就是全为\(1\)的子矩阵个数,对\(and\)的贡献就是总矩阵 ...
- 「洛谷5300」「GXOI/GZOI2019」与或和【单调栈+二进制转化】
题目链接 [洛谷传送门] 题解 按位处理. 把每一位对应的图都处理出来 然后单调栈处理一下就好了. \(and\)操作处理全\(1\). \(or\)操作处理全\(0\). 代码 #include & ...
- 【dp 状态压缩 单调栈】bzoj3591: 最长上升子序列
奇妙的单调栈状压dp Description 给出1~n的一个排列的一个最长上升子序列,求原排列可能的种类数. Input 第一行一个整数n. 第二行一个整数k,表示最长上升子序列的长度. 第三行k个 ...
- 「算法笔记」树形 DP
一.树形 DP 基础 又是一篇鸽了好久的文章--以下面这道题为例,介绍一下树形 DP 的一般过程. POJ 2342 Anniversary party 题目大意:有一家公司要举行一个聚会,一共有 \ ...
- BZOJ5125: [Lydsy1712月赛]小Q的书架【决策单调性优化DP】【BIT】【莫队】【分治】
小Q有n本书,每本书有一个独一无二的编号,现在它们正零乱地在地上排成了一排. 小Q希望把这一排书分成恰好k段,使得每段至少有一本书,然后把每段按照现在的顺序依次放到k层书架的每一层上去.将所有书都放到 ...
- Powerful array CodeForces - 86D (莫队算法)
An array of positive integers a1, a2, ..., an is given. Let us consider its arbitrary subarray al, a ...
- BZOJ.3238.[AHOI2013]差异(后缀自动机 树形DP/后缀数组 单调栈)
题目链接 \(Description\) \(Solution\) len(Ti)+len(Tj)可以直接算出来,每个小于n的长度会被计算n-1次. \[\sum_{i=1}^n\sum_{j=i+1 ...
- Educational Codeforces Round 23 D. Imbalanced Array 单调栈
D. Imbalanced Array time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
随机推荐
- 【apache】使用HttpClient,进行简单网页抓取
1 package com.lw.httpclient.test; 2 import org.apache.http.client.methods.CloseableHttpResponse; 3 i ...
- SpringBoot+MyBatis练手项目笔记汇总
以下是我在练习SpringBoot+MyBatis训练时候个人一些笔记汇总(可以点击跳转),献丑了,网上很多大佬的文章都比我写的详细,一些好的文章,我会将贴到各个内容中. 1. 插入数据返回id和内部 ...
- VS2017报错 由#define后的分号引发的【“ 应输入“)】
其实并不是第十行分号出现了问题,而是由于在宏定义后面加了分号,修改成这样即可 一开始竟然没看出来--甚至以为是VS中出现"宏可以转换为constexpr"问题--下次要仔细--
- Windows进程间通讯(IPC)----信号量
线程同步内核对象 操作系统进行进程间同步是利用信号量机制.对于windows系统而言,可以利用一些内核对象进行线程同步,因为这些内核对象可以命名并且属于系统内核,所以可以支持不同进程间的线程同步进而实 ...
- QFNU 10-02 19 training
B - Yet Another Crosses Problem 题意:找如果使图中某一行某一列全部变成黑色,至少需要把多少个白方格变成黑方格 思路:直接找就可以,注意存储的时候要记得进行分开存储,存储 ...
- BUAAOO第四单元总结与学期回顾
第四单元架构设计 第四单元要完成的是对给定UML元素的建模/统计/分析,考虑到UML元素的组织是树状的,很容易想到基于树状的数据结构完成 由于UML元素已经由官方接口给出,因此结点类采用wrapper ...
- Taro使用多线程Worker相关问题解决
JavaScript 语言采用的是单线程模型,HTML5标准中的Web Worker ,为 JavaScript 创造多线程环境.微信小程序也有相应的Worker,同样具备多线程运行的能力 主页面中创 ...
- [bug] SSM项目:Cannot load driver class: com.mysql.jdbc.Driver
检查pom文件,mysql包部分为: <dependency> <groupId>mysql</groupId> <artifactId>mysql-c ...
- 1.消息队列(queue)
版权声明:本文为博主原创文章,未经博主允许不得转载.https://www.cnblogs.com/Dana-gx/p/9724545.html 一.基本概念 IPC:Linux下的进程通信.包括6种 ...
- JDK版本升级
背景:本来安装了一个1.6版本的JDK,因为版本过低需要升级成1.8 安装过程很简单一路next,主要是遇到几个问题需要备注一下解决方法. Error opening registry key'sof ...