Codeforces Round #345 (Div. 1) D. Zip-line 上升子序列 离线 离散化 线段树
D. Zip-line
题目连接:
http://www.codeforces.com/contest/650/problem/D
Description
Vasya has decided to build a zip-line on trees of a nearby forest. He wants the line to be as long as possible but he doesn't remember exactly the heights of all trees in the forest. He is sure that he remembers correct heights of all trees except, possibly, one of them.
It is known that the forest consists of n trees staying in a row numbered from left to right with integers from 1 to n. According to Vasya, the height of the i-th tree is equal to hi. The zip-line of length k should hang over k (1 ≤ k ≤ n) trees i1, i2, ..., ik (i1 < i2 < ... < ik) such that their heights form an increasing sequence, that is hi1 < hi2 < ... < hik.
Petya had been in this forest together with Vasya, and he now has q assumptions about the mistake in Vasya's sequence h. His i-th assumption consists of two integers ai and bi indicating that, according to Petya, the height of the tree numbered ai is actually equal to bi. Note that Petya's assumptions are independent from each other.
Your task is to find the maximum length of a zip-line that can be built over the trees under each of the q assumptions.
In this problem the length of a zip line is considered equal to the number of trees that form this zip-line.
Input
The first line of the input contains two integers n and m (1 ≤ n, m ≤ 400 000) — the number of the trees in the forest and the number of Petya's assumptions, respectively.
The following line contains n integers hi (1 ≤ hi ≤ 109) — the heights of trees according to Vasya.
Each of the following m lines contains two integers ai and bi (1 ≤ ai ≤ n, 1 ≤ bi ≤ 109).
Output
For each of the Petya's assumptions output one integer, indicating the maximum length of a zip-line that can be built under this assumption.
Sample Input
4 4
1 2 3 4
1 1
1 4
4 3
4 5
Sample Output
4
3
3
4
Hint
题意
给你n个数,m个询问
每次单点修改,然后问你现在整个序列的lis长度。
修改完之后,要求修改回去。
题解:
离线做,在线的话,得用持久化线段树。我的智障队友就是持久化线段树强行在线过的。
我们维护四个东西,dp1[i]表示从1开始到第i个位置的最长上升子序列长度,dp2[i]表示从n开始到第i个位置的最长递减子序列长度。dp3[i]表示第i个询问的那个位置从1开始到第x(即询问的位置)个位置的最长上升子序列长度,dp4[i]表示递减。
假如询问是x,y那么
然后我们判断一下第x个位置是不是lis的关键位置,是的话,ans=lis。否则的话,ans=lis-1。关键位置就是这个位置是全局lis不可替代的一个数。
然后ans = max(ans,dp3[i]+dp4[i]-1)这个很显然……
然后就完了。
细节部分,就是需要离散化一下,然后就没了,感觉还是很好写的。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;
int n,m;
int a[maxn],dp1[maxn],dp2[maxn];
typedef int SgTreeDataType;
struct treenode
{
    int L , R  ;
    SgTreeDataType sum , lazy;
    void update(SgTreeDataType v)
    {
        sum = max(sum,v);
    }
};
struct Seg
{
    treenode tree[maxn*4];
    inline void push_down(int o)
    {
    }
    inline void push_up(int o)
    {
        tree[o].sum = max(tree[2*o].sum , tree[2*o+1].sum);
    }
    inline void build_tree(int L , int R , int o)
    {
        tree[o].L = L , tree[o].R = R,tree[o].sum = 0;
        if (R > L)
        {
            int mid = (L+R) >> 1;
            build_tree(L,mid,o*2);
            build_tree(mid+1,R,o*2+1);
        }
    }
    inline void update(int QL,int QR,SgTreeDataType v,int o)
    {
        int L = tree[o].L , R = tree[o].R;
        if (QL <= L && R <= QR) tree[o].update(v);
        else
        {
            push_down(o);
            int mid = (L+R)>>1;
            if (QL <= mid) update(QL,QR,v,o*2);
            if (QR >  mid) update(QL,QR,v,o*2+1);
            push_up(o);
        }
    }
    inline SgTreeDataType query(int QL,int QR,int o)
    {
        int L = tree[o].L , R = tree[o].R;
        if (QL <= L && R <= QR) return tree[o].sum;
        else
        {
            push_down(o);
            int mid = (L+R)>>1;
            SgTreeDataType res = 0;
            if (QL <= mid) res = max(res, query(QL,QR,2*o));
            if (QR > mid) res = max(res, query(QL,QR,2*o+1));
            push_up(o);
            return res;
        }
    }
}L,R;
map<int,int> H;
vector<int> P;
struct node
{
    int x,y;
}Q[maxn];
vector<pair<int,int> > Qx[maxn];
int cnt[maxn];
int dp3[maxn],dp4[maxn];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]),P.push_back(a[i]);
    for(int i=1;i<=m;i++)
        scanf("%d%d",&Q[i].x,&Q[i].y),P.push_back(Q[i].y);
    sort(P.begin(),P.end());
    P.erase(unique(P.begin(),P.end()),P.end());
    for(int i=0;i<P.size();i++)
        H[P[i]]=i+1;
    for(int i=1;i<=n;i++)
        a[i]=H[a[i]];
    for(int i=1;i<=m;i++)
        Q[i].y=H[Q[i].y],Qx[Q[i].x].push_back(make_pair(i,Q[i].y));
    L.build_tree(1,P.size()+5,1);
    for(int i=1;i<=n;i++)
    {
        dp1[i]=L.query(1,a[i]-1,1)+1;
        for(int j=0;j<Qx[i].size();j++)
        {
            int id = Qx[i][j].first;
            int x = Qx[i][j].second;
            dp3[id]=L.query(1,x-1,1)+1;
        }
        L.update(a[i],a[i],dp1[i],1);
    }
    reverse(a+1,a+1+n);
    R.build_tree(1,P.size()+5,1);
    for(int i=1;i<=n;i++)
    {
        dp2[i]=R.query(a[i]+1,P.size(),1)+1;
        for(int j=0;j<Qx[n-i+1].size();j++)
        {
            int id = Qx[n-i+1][j].first;
            int x = Qx[n-i+1][j].second;
            dp4[id]=R.query(x+1,P.size(),1)+1;
        }
        R.update(a[i],a[i],dp2[i],1);
    }
    int Lis = 0;
    for(int i=1;i<=n;i++)
        Lis = max(Lis,dp1[i]);
    for(int i=1;i<=n;i++)
        if(dp1[i]+dp2[n-i+1]==Lis+1)
            cnt[dp1[i]]++;
    for(int i=1;i<=m;i++)
    {
        int ans = Lis;
        int x = Q[i].x;
        if(dp1[x]+dp2[n-x+1]==Lis+1&&cnt[dp1[x]]==1)ans--;
        ans=max(ans,dp3[i]+dp4[i]-1);
        printf("%d\n",ans);
    }
}Codeforces Round #345 (Div. 1) D. Zip-line 上升子序列 离线 离散化 线段树的更多相关文章
- Codeforces Round #373 (Div. 2) E. Sasha and Array 矩阵快速幂+线段树
		E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input standard ... 
- Codeforces Round #345 (Div. 1)  D - Zip-line  带单点修改的LIS  主席树 | 离线树状数组
		D - Zip-line #include<bits/stdc++.h> #define LL long long #define fi first #define se second # ... 
- Codeforces Round #200 (Div. 1) D. Water Tree(dfs序加线段树)
		思路: dfs序其实是很水的东西. 和树链剖分一样, 都是对树链的hash. 该题做法是:每次对子树全部赋值为1,对一个点赋值为0,查询子树最小值. 该题需要注意的是:当我们对一棵子树全都赋值为1的 ... 
- Codeforces Round #539 (Div. 1) E - Sasha and a Very Easy Test  线段树
		如果mod是质数就好做了,但是做除法的时候对于合数mod可能没有逆元.所以就只有存一下mod的每个质因数(最多9个)的幂,和剩下一坨与mod互质的一部分.然后就能做了.有点恶心. CODE #incl ... 
- cf之路,1,Codeforces Round #345 (Div. 2)
		cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ... 
- Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum 离线+线段树
		题目链接: http://codeforces.com/contest/703/problem/D D. Mishka and Interesting sum time limit per test ... 
- Codeforces Round #276 (Div. 1) E. Sign on Fence (二分答案  主席树 区间合并)
		链接:http://codeforces.com/contest/484/problem/E 题意: 给你n个数的,每个数代表高度: 再给出m个询问,每次询问[l,r]区间内连续w个数的最大的最小值: ... 
- Codeforces Round #345 (Div. 1) C. Table Compression dp+并查集
		题目链接: http://codeforces.com/problemset/problem/650/C C. Table Compression time limit per test4 secon ... 
- Codeforces Round #345 (Div. 2) E. Table Compression 并查集
		E. Table Compression 题目连接: http://www.codeforces.com/contest/651/problem/E Description Little Petya ... 
随机推荐
- perl中的默认变量与Z/map介绍
			use v6; =begin pod @*ARGS 命令行参数, 不含脚本名 $*PROGRAM-NAME:当前运行脚本的相对路径 $*PROGRAM:当前运行脚本的文件名称 $*CWD:当前工作路径 ... 
- markdown===在新窗口中打开网址的解决办法,以及其他遗留问题!
			[超链接文字](url){:target="_blank"} 遗留问题: 如何设置图片的尺寸 我的复选框一直不生效,why? 公式 $$ 公式 $$ 不生效 如何设置代码块的背景颜 ... 
- conso.log占位符
			%d占位符表示number %s占位符表示string %f占位符表示浮点数 %o占位符表示对象 
- LeetCode解题报告—— Interleaving String
			Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. Example 1: Input: s1 = ... 
- git------删除Repository
			需求:删除仓库 Lucky-Repository,实现步骤如下截图所示 如上完成删除操作 
- 关于在ASP.NET MVC 中使用EF的Code First的方式来读取数据库时的Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
			今天在做一个小网站的时候遇到很多问题唉,我还是个菜鸟,懂的也不多,今天一个表单的提交按钮用不了,都弄了几个小时唉.不过最后还是搞定了,还有浏览器有开发人员选项,不然我都不知道我还要继续排查多久哦,今天 ... 
- CentOS按电源键关机
			chkconfig --list查看没有acpid服务.安装之后解决yum install acpid -y 安装后需要重启,不然会提示:* Starting acpid ...acpid: can' ... 
- Windows 10 安装 Mongodb
			因为新换了Windows 10 电脑,需要在新电脑重新安装所有的软件,包括mongodb 下载文件:首先在mongodb的官方网站上下载最新版本的mongodb安装程序,https://www.mon ... 
- 获取或设置config节点值
			ExeConfigurationFileMap 这个类提供了修改.获取指定 config 的功能:新建一个 ExeConfigurationFileMap 的实例 ecf :并设置 ExeConfig ... 
- 234. Palindrome Linked List【Easy】【判断链表是否回文】
			Given a singly linked list, determine if it is a palindrome. Example 1: Input: 1->2 Output: false ... 
