zoukankan      html  css  js  c++  java
  • NOI十连测 第四测 T2

     思路:线段树套可持久化treap,可持久化treap我还是第一次听说。。

    改题的时候没看数据范围。。乱开数组T_T

      1 #include<algorithm>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<time.h>
      7 #include<bits/stdc++.h>
      8 #include<ext/rope>
      9 using namespace std;
     10 using namespace __gnu_cxx;
     11 int n;
     12 int read(){
     13     int t=0,f=1;char ch=getchar();
     14     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
     15     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
     16     return t*f;
     17 }
     18 struct treaps{
     19     int ch[30001005][2],rnd[30001005],size[30001005],num[30001005],tt;
     20     int newnode(int s=0){
     21         if (tt>30000005) assert(0);
     22         ++tt;
     23         ch[tt][0]=ch[s][0];
     24         ch[tt][1]=ch[s][1];
     25         if (s) rnd[tt]=rnd[s];else rnd[tt]=rand();
     26         size[tt]=size[s];
     27         num[tt]=num[s];
     28         return tt;
     29     }
     30     void updata(int k){
     31         size[k]=1+size[ch[k][0]]+size[ch[k][1]];
     32     }
     33     int getsize(int k){
     34         return size[k];
     35     }
     36     int merge(int s,int t){
     37         if (!s||!t) return s+t;
     38         if (rnd[s]>rnd[t]){
     39             int d=newnode(s);
     40             ch[d][1]=merge(ch[d][1],t);
     41             updata(d);
     42             return d;
     43         }else{
     44             int d=newnode(t);
     45             ch[d][0]=merge(s,ch[d][0]);
     46             updata(d);
     47             return d;
     48         }
     49     }
     50     pair<int,int> split(int s,int k){
     51         if (!s) return make_pair(0,0);
     52         if (size[ch[s][0]]>=k){
     53             pair<int,int> ls=split(ch[s][0],k);
     54             int d=newnode(s);
     55             ch[d][0]=ls.second;updata(d);
     56             return pair<int,int>(ls.first,d);
     57         }
     58         pair<int,int> ls=split(ch[s][1],k-size[ch[s][0]]-1);
     59         int d=newnode(s);
     60         ch[d][1]=ls.first;updata(d);
     61         return pair<int,int>(d,ls.second);
     62     }
     63     void clear(int &s){
     64         s=0;
     65     }
     66     void push_back(int &s,int w){
     67         int d=newnode();size[d]=1;num[d]=w;
     68         s=merge(s,d);
     69     }
     70     void pop_back(int &s){
     71         s=split(s,size[s]-1).first;
     72     }
     73     int findkth(int s,int k){
     74         if (size[ch[s][0]]>=k) return findkth(ch[s][0],k);
     75         if (size[ch[s][0]]+1==k) return num[s];
     76         return findkth(ch[s][1],k-size[ch[s][0]]-1);
     77     }
     78 }treap;
     79 struct segment{
     80     int tt,l[4001005],r[4001005];
     81     int ins[4001005];
     82     int erz[4001005];
     83     int build(int ql=1,int qr=n){
     84         int t=++tt;
     85         int mid=(ql+qr)>>1;
     86         if (ql==qr) return t;
     87         l[t]=build(ql,mid);
     88         r[t]=build(mid+1,qr);
     89         return t;
     90     }
     91     void pushdown(int root){
     92         if (erz[root]){
     93             if (treap.getsize(ins[l[root]])<=erz[root]){
     94                 erz[l[root]]+=erz[root]-treap.getsize(ins[l[root]]);
     95                 treap.clear(ins[l[root]]);
     96             }else ins[l[root]]=treap.split(ins[l[root]],treap.getsize(ins[l[root]])-erz[root]).first;
     97             
     98             if (treap.getsize(ins[r[root]])<=erz[root]){
     99                 erz[r[root]]+=erz[root]-treap.getsize(ins[r[root]]);
    100                 treap.clear(ins[r[root]]);
    101             }else ins[r[root]]=treap.split(ins[r[root]],treap.getsize(ins[r[root]])-erz[root]).first;
    102             erz[root]=0;
    103         }
    104         if (treap.getsize(ins[root])){
    105             ins[l[root]]=treap.merge(ins[l[root]],ins[root]);
    106             ins[r[root]]=treap.merge(ins[r[root]],ins[root]);
    107             treap.clear(ins[root]);
    108         }
    109     }
    110     void push(int root,int ql,int qr,int w,int pl=1,int pr=n){
    111         if ((ql==pl)&&(pr==qr)){
    112             treap.push_back(ins[root],w);
    113             return;
    114         }
    115         pushdown(root);
    116         int mid=(pl+pr)>>1;
    117         if (ql<=mid) push(l[root],ql,min(qr,mid),w,pl,mid);
    118         if (qr>mid) push(r[root],max(mid+1,ql),qr,w,mid+1,pr);
    119     }
    120     void pop(int root,int ql,int qr,int pl=1,int pr=n){
    121         if ((ql==pl)&&(qr==pr)){
    122             if (treap.getsize(ins[root])) treap.pop_back(ins[root]);
    123             else erz[root]++;
    124             return;
    125         }
    126         pushdown(root);
    127         int mid=(pl+pr)>>1;
    128         if (ql<=mid) pop(l[root],ql,min(mid,qr),pl,mid);
    129         if (qr>mid) pop(r[root],max(ql,mid+1),qr,mid+1,pr);
    130     }
    131     void work(int root,int s,int k,int pl=1,int pr=n){
    132         if (pl==pr){
    133             if (treap.getsize(ins[root])<k) printf("Error
    ");
    134             else
    135             printf("%d
    ",treap.findkth(ins[root],treap.getsize(ins[root])-k+1));
    136             return;
    137         }
    138         pushdown(root);
    139         int mid=(pl+pr)>>1;
    140         if (s<=mid) work(l[root],s,k,pl,mid);
    141         else work(r[root],s,k,mid+1,pr);
    142     }
    143 }seg;
    144 int main(){
    145     n=read();int q=read();
    146     seg.build();
    147     while (q--){
    148         int opt=read();
    149         if (opt==0){
    150             int l=read(),r=read(),x=read();
    151             seg.push(1,l,r,x);
    152         }else
    153         if (opt==1){
    154             int l=read(),r=read();
    155             seg.pop(1,l,r);
    156         }else
    157         if (opt==2)
    158         {
    159             int s=read(),k=read();
    160             seg.work(1,s,k);
    161         }
    162     }
    163 }
  • 相关阅读:
    绘制图形(-)
    数字金字塔
    固定行数输出
    [原创]java WEB学习笔记70:Struts2 学习之路-- 输入验证,声明式验证,声明是验证原理
    [原创]java WEB学习笔记70:Struts2 学习之路-- struts2拦截器源码分析,运行流程
    [原创]java WEB学习笔记69:Struts2 学习之路-- 消息处理与国际化,概述,配置国际资源文件,访问国际化消息,通过超链接切换语言
    [原创]java WEB学习笔记68:Struts2 学习之路-- 类型转换与复杂属性配合使用
    [原创]java WEB学习笔记67:Struts2 学习之路-- 类型转换概述, 类型转换错误修改,如何自定义类型转换器
    [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈
    [原创]java WEB学习笔记65:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) ModelDriven拦截器 paramter 拦截器
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5599468.html
Copyright © 2011-2022 走看看