zoukankan      html  css  js  c++  java
  • (线段树)UESTC 360-Another LCIS

    For a sequence S1,S2,,SNS1,S2,⋯,SN, and a pair of integers (i,j)(i,j), if 1ijN1≤i≤j≤N and Si<Si+1<Si+2<<Sj1<SjSi<Si+1<Si+2<⋯<Sj−1<Sj, then the sequence Si,Si+1,,SjSi,Si+1,⋯,Sj is a CIS (Continuous Increasing Subsequence). The longest CIS of a sequence is called the LCIS (Longest Continuous Increasing Subsequence).

    In this problem, we will give you a sequence first, and then some add operations and some query operations. An add operation adds a value to each member in a specified interval. For a query operation, you should output the length of the LCIS of a specified interval.

    Input

    The first line of the input is an integer TT, which stands for the number of test cases you need to solve.

    Every test case begins with two integers NN, QQ, where NN is the size of the sequence, and QQ is the number of queries. S1,S2,,SNS1,S2,⋯,SN are specified on the next line, and then QQ queries follow. Every query begins with a character a or qa is followed by three integers LL, RR, VV, meaning that add VV to members in the interval [L,R][L,R] (including LL, RR), and q is followed by two integers LL, RR, meaning that you should output the length of the LCIS of interval [L,R][L,R].

    T10T≤10;

    1N,Q1000001≤N,Q≤100000;

    1LRN1≤L≤R≤N;

    10000S1,S2,,SN,V10000−10000≤S1,S2,⋯,SN,V≤10000.

    Output

    For every test case, you should output Case #k: on a single line first, where kkindicates the case number and starts at 11. Then for every q query, output the answer on a single line. See sample for more details.

    Sample Input

    1
    5 6
    0 1 2 3 4 
    q 1 4
    a 1 2 -10
    a 1 1 -6
    a 5 5 -4
    q 2 3
    q 4 4

    Sample Output

    Case #1:
    4
    2
    1

    线段树维护各个左闭右开区间。需要注意的是区间合并的条件,为方便判断,每个结点记录这个区间左右两侧的值,方便进行比较能否合并。每次查询、修改的时候,没完全在目标区间内的时候
    不要忘记将之前未传下去的改变传递下去。
      1 #include <iostream>
      2 //#include<bits/stdc++.h>
      3 #include <stack>
      4 #include <queue>
      5 #include <map>
      6 #include <set>
      7 #include <cstdio>
      8 #include <cstring>
      9 #include <algorithm>
     10 #include <math.h>
     11 using namespace std;
     12 typedef long long ll;
     13 typedef unsigned long long ull;
     14 const int MAX=1e5+5;
     15 struct node
     16 {
     17     int left,right,mid;//分别表示从区间左侧开始最长的单调子序列,区间中最长,以右侧结尾的最长单调子序列长度
     18     int x,y;//区间左侧的值,右侧的值
     19     int num;
     20 }st[10*MAX];
     21 //int col[10*MAX];
     22 void pushup(int l,int r,int k)
     23 {
     24     st[k].left=st[2*k].left;
     25     st[k].right=st[2*k+1].right;
     26     st[k].mid=max(st[2*k].mid,st[2*k+1].mid);
     27     st[k].x=st[2*k].x;
     28     st[k].y=st[2*k+1].y;
     29     if(st[2*k].y<st[2*k+1].x)
     30     {
     31         st[k].mid=max(st[k].mid,st[2*k].right+st[2*k+1].left);
     32         if(st[2*k].left==(l+r)/2-l)
     33             st[k].left=st[2*k].left+st[2*k+1].left;
     34         if(st[2*k+1].right==r-(l+r)/2)
     35             st[k].right=st[2*k+1].right+st[2*k].right;
     36     }
     37 }
     38 void pushdown(int k)
     39 {
     40     if(st[k].num)
     41     {
     42         st[2*k].num+=st[k].num;
     43         st[2*k+1].num+=st[k].num;
     44         st[2*k].x+=st[k].num;
     45         st[2*k].y+=st[k].num;
     46         st[2*k+1].x+=st[k].num;
     47         st[2*k+1].y+=st[k].num;
     48         st[k].num=0;
     49     }
     50 }
     51 void init(int l,int r,int k)
     52 {
     53     if(l+1==r)
     54     {
     55         st[k].left=st[k].right=st[k].mid=1;
     56         scanf("%d",&st[k].num);
     57         st[k].x=st[k].y=st[k].num;
     58         return;
     59     }
     60     st[k].num=0;
     61     init(l,(l+r)/2,2*k);
     62     init((l+r)/2,r,2*k+1);
     63     pushup(l,r,k);
     64 }
     65 void update(int ul,int ur,int l,int r,int k,int z)//[ul,ur)是目标区间,[l,r)是当下区间,z是加的值
     66 {
     67     if(l>=ul&&r<=ur)
     68     {
     69         st[k].num+=z;
     70         st[k].x+=z;
     71         st[k].y+=z;
     72         return;
     73     }
     74     pushdown(k);
     75     if(l+1==r)
     76         return;
     77     int m=(l+r)/2;
     78     if(ul<m)
     79         update(ul,ur,l,m,2*k,z);
     80     if(ur>m)
     81         update(ul,ur,m,r,2*k+1,z);
     82     pushup(l,r,k);
     83 }
     84 int query(int ql,int qr,int l,int r,int k)//[ql,qr)是查询区间,[l,r)是当下区间
     85 {
     86     if(l>=ql&&r<=qr)
     87         return st[k].mid;
     88     pushdown(k);
     89     int m=(l+r)/2;
     90     int maxn;
     91     if(ql<m)
     92     {
     93         if(qr<=m)
     94             return query(ql,qr,l,m,2*k);
     95         else
     96             {
     97                 maxn=max(query(ql,qr,l,m,2*k),query(ql,qr,m,r,2*k+1));
     98                 if(st[2*k].y<st[2*k+1].x)
     99                 {
    100                     maxn=max(maxn,min(m-ql,st[2*k].right)+min(qr-m,st[2*k+1].left));
    101                 }
    102                 return maxn;
    103             }
    104     }
    105     else
    106         return query(ql,qr,m,r,2*k+1);
    107 }
    108 int t;
    109 int N,Q;
    110 int main()
    111 {
    112     scanf("%d",&t);
    113     char tem[10];
    114     int l,r,zhi;
    115     for(int i=1;i<=t;i++)
    116     {
    117         printf("Case #%d:
    ",i);
    118         scanf("%d %d",&N,&Q);
    119         init(1,N+1,1);
    120         for(int j=1;j<=Q;j++)
    121         {
    122             scanf("%s",tem);
    123             if(tem[0]=='q')
    124             {
    125                 scanf("%d %d",&l,&r);
    126                 printf("%d
    ",query(l,r+1,1,N+1,1));
    127             }
    128             else
    129             {
    130                 scanf("%d %d %d",&l,&r,&zhi);
    131                 update(l,r+1,1,N+1,1,zhi);
    132             }
    133         }
    134     }
    135 }
    
    
    
     
  • 相关阅读:
    2.采用字符的移位方式实现字符文本加密解密。
    用自己的算法实现startsWith和endsWith功能。
    采用多种算法,模拟摇奖:从1-36中随机抽出8个不重复的数字
    输入5个数用冒泡排序进行从小到大排列
    题目六:控制台输入年龄,根据年龄输出不同的提示
    题目五:控制台输出三角形和菱形
    题目四:控制台输出九九乘法表
    百马百担
    classNum 表示学生的班号,例如“class05”。 有如下List  List list = new ArrayList();
    已知有十六支男子足球队参加2008 北京奥运会。写一个程序,把这16 支球队随机分为4 个组。采用List集合和随机数     2008 北京奥运会男足参赛国家:  科特迪瓦,阿根廷,澳大利亚,塞尔维亚,荷兰,尼日利亚、日本,美国,中国,新西 兰,巴西,比利时,韩国,喀麦隆,洪都拉斯,意大利
  • 原文地址:https://www.cnblogs.com/quintessence/p/6428877.html
Copyright © 2011-2022 走看看