4358: permu

链接

分析:

  不删除的莫队+可撤销的并查集。

  每次询问先固定左端点到一个块内,然后将这些右端点从小到大排序,然后询问的过程中,右端点不断往右走,左端点可能会撤销,但是移动区间不超过$\sqrt n$个,用带撤销的并查集维护。

  复杂度$O(n \sqrt n log n)$

代码:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<bitset>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
int bel[N], a[N], ans[N], fa[N], dep[N], B, Top, Mx, n;
bool vis[N];
struct Que{ int l, r, id; } ;
struct Node{ int x, d; } sk[N << ]; // N * 2 !!!
bool operator < (const Que &A,const Que &B) { return A.r < B.r; }
vector< Que > q[N]; int solve1(int x,int y) {
if (x == y) return ;
vector<int>vec;
for (int i = x; i <= y; ++i) vec.push_back(a[i]);
sort(vec.begin(), vec.end());
int res = , now = ;
for (int i = ; i < (int)vec.size(); ++i)
vec[i] == vec[i - ] + ? now ++ : now = , res = max(res, now); // !!!
return res;
}
int find(int x) {
return x == fa[x] ? x : find(fa[x]);
}
void Union(int x,int y) {
x = find(x), y = find(y);
if (x == y) return ;
if (dep[x] < dep[y]) swap(x, y);
Mx = max(Mx, dep[x] + dep[y]);
fa[y] = x;
sk[++Top] = (Node){x, dep[x]};
sk[++Top] = (Node){y, dep[y]};
dep[x] += dep[y];
}
void add(int x) {
vis[x] = ;
if (vis[x - ]) Union(x - , x);
if (vis[x + ]) Union(x, x + );
}
void solve(int now,vector<Que> &vec) {
Top = , Mx = ;
int pos = min(N, now * B) + , lastpos, lastmx, L = pos, R = pos - ;
for (int i = ; i <= n; ++i) fa[i] = i, dep[i] = , vis[i] = ;
for (int i = ; i < (int)vec.size(); ++i) {
Que v = vec[i];
while (R < v.r) add(a[++R]);
lastmx = Mx, lastpos = Top;
while (L > v.l) add(a[--L]);
ans[v.id] = Mx;
Mx= lastmx;
while (Top > lastpos) fa[sk[Top].x] = sk[Top].x, dep[sk[Top].x] = sk[Top].d, Top --;
while (L < pos) vis[a[L ++]] = ;
}
}
int main() {
n = read();int m = read(); B = sqrt(n);
for (int i = ; i <= n; ++i) a[i] = read(), bel[i] = (i - ) / B + ;
for (int i = ; i <= m; ++i) {
int x = read(), y = read();
if (bel[x] == bel[y]) ans[i] = solve1(x, y);
else q[bel[x]].push_back((Que){x, y, i});
}
for (int i = ; i <= bel[n]; ++i) sort(q[i].begin(), q[i].end()), solve(i, q[i]);
for (int i = ; i <= m; ++i) printf("%d\n", ans[i]);
return ;
}

4358: permu的更多相关文章

  1. bzoj 4358 Permu - 莫队算法 - 链表

    题目传送门 需要高级权限的传送门 题目大意 给定一个全排列,询问一个区间内的值域连续的一段的长度的最大值. 考虑使用莫队算法. 每次插入一个数$x$,对值域的影响可以分成4种情况: $x - 1$, ...

  2. bzoj 4358 permu

    比较容易想到莫队算法+线段树,但是这样时间复杂度是O(nsqrtnlogn)无法通过,考虑如果不进行删除操作,只有添加操作的话那么并查集就可以实现了,于是可以设定sqrtn块,每个块范围为(i-1)* ...

  3. bzoj 4358: permu 莫队

    第一步先莫队分块. 对于每一块l~r,初始右端点设为r+1,然后每个询问先将右端点往右移,然后处理询问在l~r之间的部分,最后用一个栈再把l~r的复原. 具体来说是维护两个数组now1和now2,一个 ...

  4. 【BZOJ】4358: permu 莫队算法

    [题意]给定长度为n的排列,m次询问区间[L,R]的最长连续值域.n<=50000. [算法]莫队算法 [题解]考虑莫队维护增加一个数的信息:设up[x]表示数值x往上延伸的最大长度,down[ ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. HDU 4358 Boring counting(莫队+DFS序+离散化)

    Boring counting Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Others) ...

  7. 【DP】permu

    permu [Description] 给定两个1~N的全排列A,B.有两个指针q和p,一开始q.p都为0,可执行以下三种操作: 1.q+1:2.p+1:3.q+1且p+1(Aq+1≠Bp+1时才可以 ...

  8. bnu 4358 左手定则 (搜索)

    http://www.bnuoj.com/bnuoj/problem_show.php?pid=4358 [题意]:给定起始位置和方向和目的地,按照左转.前进.右转.后退的优先级递减,也就是说能左转就 ...

  9. 【HDOJ】4358 Boring counting

    基本思路是将树形结构转线性结构,因为查询的是从任意结点到叶子结点的路径.从而将每个查询转换成区间,表示从该结点到叶子结点的路径.离线做,按照右边界升序排序.利用树状数组区间修改.树状数组表示有K个数据 ...

随机推荐

  1. beego+vue.js分离开发,结合发布,简单部署

    大家知道,golang开发的东西部署简单是它很大的卖点,一般的应用,生成的可执行文件直接放服务器上运行即可,不需要任何环境.当然,大型的应用才需要比如mysql,nginx等. 但是当vue.js出现 ...

  2. Git 恢复本地误删的文件

    通过git进行代码管理的项目,如果在本地编辑的过程中误删了某些文件或者文件夹,可以通过git操作来复原. Step 1: git status 查看本地对改动的暂存记录.如下图所示,本人误删了文件夹“ ...

  3. 解决Firefox下,页面元素不刷新问题

    由于FireFox的刷新机制与IE有较大区别.所以javascript代码 document.location.reload();通常在IE上工作正常,在Firefox下效果却并不理想,这是因为Fir ...

  4. [20171101]修改oracle口令安全问题.txt

    [20171101]修改oracle口令安全问题.txt --//等保的问题,做一些关于修改oracle口令方面的测试. 1.oracle修改口令一般如下方式: alter user scott id ...

  5. VisualStudio编译项目时,提示bin目录和obj目录下的文件不能写的错误处理的解决办法

    具体错误信息如下: Error 139 Could not write lines to file "obj\Debug\SanSuiWeb.csproj.FileListAbsolute. ...

  6. mysql中case的一个例子

    最近遇到一个问题: year amount num 1991 1 1.1 1991 2 1.2 1991 3 1.3 1992 1 2.1 1992 2 2.2 1992 3 3.3 把上面表格的数据 ...

  7. 在Eclipse中使用Maven jetty的debug模式

    1.右键项目debug as添加mvn命令: jetty:run 2.进入eclipse的菜单Run->Debug configurations,会看到maven build下对应的项目的mvn ...

  8. linux之基本命令进阶

    一  配置yum源管理与软件管理  yum常见工具 tree telent sl  cowsay yum install tree #安装tree命令,以树形目录显示 #由于每次安装都有确认的提示,取 ...

  9. 转://UDEV简介及配置过程

    在Linux环境下安装Oracle11g RAC时,OS层面配置好多路径软件后(multipath),下一步就需要配置udev或asmlib来处理共享分区(Lun),以便Orace ASM能够看到这些 ...

  10. P2665 [USACO08FEB]连线游戏Game of Lines

    本着dp的心情,结果是道水题STL  set就行了 题意:看有多少种斜率(题在那里半天说多少直线(不平行的)),其实就是找斜率的种类 #include<cstdio> #include&l ...