• I


    题意  :一段区间  操作1 切断点 操作2 恢复最近切断的一个点 操作3 单点查询该点所在最大连续区间

    思路:  主要是push_up :  设区间x 为母区间  x<<1 ,x<<1|1分别为两个子区间  

      x的左端连续子段和 :当x<<1区间没有断开 也就是 x<<1 的最大连续子段ml ==tree[x<<1].r-tree[x<<1].l+1 等于区间长度时 x左端连续字段和tree[x].ll=tree[x<<1].ll+tree[x<<1|1].ll如果断开了直接就等于左子区间

    最大子段和 

    x的右端连续子区间同理

    x的最大连续子区间   x的最大连续子区间只可能在  1. 以x的Mid为分界   左子区最大连续和  2.右子区最大连续和 3.横跨mid  前两个分别直接区子区间的就能 第三个长度等于tree[x<<1].rl+tree[x<<1|1].ll 取三个里面最大即可

    查询: 如果查询的点t 当前所查询的区间tree[x].ml最大连续子段和直接等于0 或者 tree[x].l==tree[x].r时 或者  区间是完整的 也就是tree[x].ml=tree[x].r-tree[x].l+1 时都可以直接返回

    不然  令mid=l+r>>1  如果要查询的点t 在mid左边(包括Mid)那么当t 位于区间tree[x<<1]的从右开始的最长连续区间时  还可以把与其相邻的子区间tree[x<<1|1].ll接上  如果不位于 直接往下面查即可  

    如果要查询的点t 在mid右边(不包括Mid)同理

    记得循环输入

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=50000;
     4 struct Node{
     5     int l,r;
     6     long long  ll,rl,ml;
     7 }tree[maxn*4];
     8 void build(int x,int l,int r){
     9     tree[x].l=l,tree[x].r=r;
    10     tree[x].ll=tree[x].rl=tree[x].ml=r-l+1;
    11     if(l==r)return ;
    12     else {
    13         int mid=l+r>>1;
    14         build(x<<1,l,mid);
    15         build(x<<1|1,mid+1,r);
    16     }
    17 }
    18 void push_up(int x){
    19         tree[x].ll=tree[x<<1].ll;
    20         tree[x].rl=tree[x<<1|1].rl;
    21         tree[x].ml=max(tree[x<<1].ml,tree[x<<1|1].ml);
    22         tree[x].ml=max(tree[x].ml,tree[x<<1].rl+tree[x<<1|1].ll);
    23         if(tree[x<<1].ll==tree[x<<1].r-tree[x<<1].l+1)tree[x].ll+=tree[x<<1|1].ll;
    24         if(tree[x<<1|1].rl==tree[x<<1|1].r-tree[x<<1|1].l+1)tree[x].rl+=tree[x<<1].rl;
    25 }
    26 void update(int x,int t,int val){
    27     if(tree[x].l==tree[x].r){
    28         if(val==1)tree[x].ll=tree[x].rl=tree[x].ml=1;
    29         else tree[x].ll=tree[x].rl=tree[x].ml=0;
    30         return ;
    31     }
    32     else {
    33         int mid=tree[x].l+tree[x].r>>1;
    34         if(t<=mid)update(x<<1,t,val);
    35         else update(x<<1|1,t,val);
    36         push_up(x);
    37     }
    38 }
    39 long long  query(int x,int t){
    40     if(tree[x].l==tree[x].r||tree[x].ml==0||tree[x].ml==tree[x].r-tree[x].l+1){
    41         return tree[x].ml;
    42     }
    43     else {
    44         int mid=tree[x].l+tree[x].r>>1;
    45         if(t<=mid){
    46             if(t>=tree[x<<1].r-tree[x<<1].rl+1){
    47                 return query(x<<1,t)+query(x<<1|1,mid+1);
    48             }
    49             else return query(x<<1,t);
    50         }
    51         else {
    52             if(t<=tree[x<<1|1].l+tree[x<<1|1].ll-1){
    53                 return query(x<<1|1,t)+query(x<<1,mid);
    54             }
    55             else return query(x<<1|1,t);
    56         }    
    57     }
    58 
    59 }
    60 int Q[maxn];
    61 int main(){
    62     int n,q;
    63     while(scanf("%d%d",&n,&q)==2){
    64     build(1,1,n);
    65     int t=1;
    66     //int last=0;
    67     int top=0;
    68     for(int i=1;i<=q;i++){
    69         char s[10];
    70         scanf("%s",s);
    71         if(s[0]=='D'){
    72             scanf("%d",&t);
    73             Q[top++]=t;
    74             update(1,t,0);
    75         }
    76         if(s[0]=='Q'){
    77             scanf("%d",&t);
    78             printf("%lld
    ",query(1,t));
    79         }
    80         if(s[0]=='R'){
    81             update(1,Q[--top],1);
    82         }
    83     }
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    dfadfas
    Sqlserver修改文件目录,包括系统数据库
    VS2013 产品密钥所有版本
    win11 取消右键更多选项
    VS2013 产品密钥所有版本
    CronTrigger表达式
    C#语言Windows服务程序测试网站发送HTTP请求超时解决办法
    未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\705b2e0e\c6ba7a68\App_global.asax.v9
    SQL跨数据库复制表数据<转载>
    “服务器应用程序不可用”解决方法
  • 原文地址:https://www.cnblogs.com/ttttttttrx/p/10312237.html
Copyright © 2020-2023  润新知