cf1143E 倍增好题!

一开始感觉用莫队可以搞一下,但是看了题解才发现这题其实是倍增套路题

把排列转换成nxt数组,然后倍增dp[i][j]表示第i个数后面有(1<<j)个数的最靠左的区间

然后从右往左扫一次即可

#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
int dp[maxn][20],last[maxn],nxt[maxn],ans[maxn],a[maxn],b[maxn],n,m,t;
//dp[i][j]表示第i个数开始的后面(1<<j)个数的位置
int main(){
    cin>>n>>m>>t;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++)nxt[a[i-1]]=a[i];
    nxt[a[n]]=a[1];
    for(int i=1;i<=m;i++)cin>>b[i];
    for(int i=1;i<=n;i++)last[i]=m+1;
    for(int i=0;i<=19;i++)dp[m+1][i]=m+1;
    ans[m+1]=m+1;
    for(int i=m;i>=1;i--){
        dp[i][0]=last[nxt[b[i]]];
        last[b[i]]=i;
        for(int j=1;j<=19;j++)dp[i][j]=dp[dp[i][j-1]][j-1];
        int cnt=n-1,pos=i;
        for(int j=19;j>=0;j--)
            if(cnt >= (1<<j))
                cnt-=(1<<j),pos=dp[pos][j];
        ans[i]=min(ans[i+1],pos);
    }
    for(int i=1;i<=t;i++){
        int l,r;
        cin>>l>>r;
        if(ans[l]<=r)cout<<"1";
        else cout<<"0";
    }
}

原文地址:https://www.cnblogs.com/zsben991126/p/10638911.html

时间: 2024-10-11 21:28:19

cf1143E 倍增好题!的相关文章

【BZOJ4569】萌萌哒(并查集,倍增)

[BZOJ4569]萌萌哒(并查集,倍增) 题面 BZOJ 题意: 有一个长度为\(n\)的数 给定\(m\)个限制条件 每次限制\(l1-r1\)与\(l2-r2\)是相同的 求出方案数 题解 如果每次给定的限制都是告诉你某一位和某一位是相同的 那么,我们的做法是: 并查集,然后计算有\(k\)个联通块 \(ans=9*10^{k-1}\) 但是,现在每次给定的都是一个区间 我们不太可能暴力的把区间之间的位置两两进行一次合并 所以,我们来想个办法优化一下. 试试倍增? 维护\(logn\)个并

SPOJ QTREE2 (LCA - 倍增 在线)

You are given a tree (an undirected acyclic connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. Each edge has an integer value assigned to it, representing its length. We will ask you to perfrom some instructions of the following form: D

【题解】HDU Homework(倍增)

[题解]HDU Homework(倍增) 矩阵题一定要多多检查一下是否行列反了... 一百个递推项一定要存101个 说多了都是泪啊 一下午就做了这一道题因为实在是太菜了太久没写这种矩阵的题目... 设一个行向量\(e\),和一个增逛矩阵\(A\),他们咋定义的见我那篇讲线性递推博客 现在我们再预处理\(st\)矩阵数组,其中\(st_i=A^{2^i}\). 考虑这样一种做法,我们考虑让\(e\)总共有101个值,然后当第一个值被增逛为\(f_{q.n-100}\)时,暴力将\(e\)中的第\(

20170303

今天考了一场奇怪的考试. 第一题, 大意:给定一个序列,从这个序列中取出一些数,使这些数字的平均数减去中位数最大. n<=200000. 题解: 这种题一看就是sort一下,枚举一维,二分或数据结构一维.复杂度O(nlogn). 实际这道题也就是这样了,枚举中位数,三分两端的数数量,然后就没了. 第二题: 大意:求存在多少排列任意两相邻数字差绝对值不为1.n<=1000 题解:比赛是没想出来,实际dp,至于怎么dp自己脑补. 第三题: 大意:求存在多少由1,2,3,5,7组成的数符合它不是2,

codevs3305 水果姐逛水果街Ⅱ

本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! 题目描述 Description 水果姐第二天心情也很不错,又来逛水果街. 突然,cgh又出现了.cgh施展了魔法,水果街变成了树结构(店与店之间只有一条唯一的路径). 同样还是n家水果店,编号为1~n,每家店能买水果也能卖水果,并且同一家店卖与买的价格一样

午学树链剖分有感~

今天上课谈到树链剖分,被机房某dalao嘲讽了一波,决定冒着不听课的风险学链剖 关于这篇blog的灵感来源:传送门,不妥删 1.0前置知识 1.1链式向前星 这个应该都会吧,但还是附上讲解,这个图很易懂啊,蒟蒻当时一直没学懂,看了图才发现自己有多弱智 1.2dfs序 这个学长上课讲的随便找了一个讲解,仅供参考:传送门 1.3线段树 线段树应该都学了,就不附连接了 1.4为什么要学链剖 小蒟蒻没怎么做过树上倍增和链剖的题,但据说树上倍增的题链剖都能做,但链剖的题树上倍增不一定能做 2.0正文 2.

【BZOJ2815】【ZJOI2012】灾难 阿米巴和小强题 动态倍增LCA 灾难树

广告: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44104163"); } 题意: 原题面请见JSShining博客 http://www.cnblogs.com/JS-Shining/archive/2013/01/12/2857429.html 题解: 我们构建一颗灾难树,使得一

P1081 开车旅行[倍增](毒瘤题)

其实就是个大模拟. 首先,根据题意,小A和小B从任意一个城市开始走,无论\(X\)如何,其路径是一定唯一的. 显然对于两问都可以想出一个\(O(n^2)\)的暴力,即直接一步一步地向右走. 首先,我们当然需要知道A,B在每个城市的下一步如何走,记\(nexta(i),nextb(i)\)为A,B在\(i\)处时,下一步走到的城市编号. 考虑如何高效(复杂度小于等于\(O(nlogn)\))维护两个\(next\). 显然不能直接维护每个城市与其后面的城市的差值,再好的数据结构也会到\(O(n^2

51nod2621 树上距离一题四解ST表+倍增+Tarjan+树剖

LCA裸题 只有代码无原理,给自己复习用 1. ST表(这题2^10就够了) 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=2e3+50; 5 6 int cnt,dfn[maxn],dep[maxn],dp[maxn][21],lg2[maxn],dis[maxn],w[maxn][maxn]; 7 std::vector<int> G[maxn]; 8 void dfs(int u,in