zoukankan      html  css  js  c++  java
  • 玲珑oj 1117 线段树+离线+离散化,laz大法

    1117 - RE:从零开始的异世界生活

    Time Limit:1s Memory Limit:256MByte

    Submissions:438Solved:68

    DESCRIPTION

    486到了异世界,看到了一群可爱的妹子比如蕾姆啊,艾米莉亚啊,拉姆啊,白鲸啊,怠惰啊等等!
    有一天膜女告诉486说她的能力可能不能再用了,因为膜女在思考一个数据结构题,没心情管486了。
    486说我来帮你做,膜女说你很棒棒哦!

    给一个集合,最开始为空(不是数学上的集合)
    五个操作:

    1、插入x
    2、把小于x的数变成x
    3、把大于x的数变成x
    4、求集合中第x小数
    5、求集合中小于x的数个数

    INPUT
    第一行一个数m 后面有m行,每行格式为opt x,opt表示是什么操作,x表示操作的值
    OUTPUT
    对于每个4,5操作,输出一个值表示答案
    SAMPLE INPUT
    5 1 1 1 3 4 1 2 33 4 1
    SAMPLE OUTPUT
    1 33
    HINT
    m <= 100000 , x <= 1000000000
    SOLUTION
    这个题目是暑假前玲珑的一次我参加的比赛,很遗憾当时还很弱不会ST直接放弃了,现在又回来看见,当时看别人博客题解是什么值域线段树,好吧我也不会,
    copy一个代码跑了960+ms险过感觉怎么这么慢捏,再次看题目感觉就是普通线段树就可做。
    虽然n<1e9,但m最大10w,最多也就10w个不同的x,我想到用map离散化处理一下,为了方便询问我是从2开始的,由于要对所有的x离散化,所以必须先离散化结束才能应对所有的询问,这里采用了离线的作法,先保存询问值,预处理完在依次模拟询问的过程。
    没有很奇葩的询问,单点更新,区间修改和二分查找,注意细节的话就好了。
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define inf 0x3f3f3f3f
      4 #define LL long long
      5 #define MAX 100005
      6 map<int,int>M1;
      7 int N,x[MAX]={2147483647},P[MAX];
      8 struct Ask
      9 {
     10   int opt,x;
     11 }a[MAX];
     12 struct SegTree
     13 {
     14   #define M ((L+R)>>1)
     15   #define lc (id<<1)
     16   #define rc (id<<1|1)
     17   int sum[MAX<<2],laz[MAX<<2];//laz[i]表示全部变为i
     18   void init()
     19   {
     20       memset(sum,0,sizeof(sum));
     21       memset(laz,-1,sizeof(laz));
     22   }
     23   void pushup(int L,int R,int id)
     24   {
     25       sum[id]=sum[lc]+sum[rc];
     26   }
     27   void pushdown(int L,int R,int id)
     28   {
     29       if(laz[id]!=-1){
     30         sum[lc]=sum[rc]=0;
     31         laz[lc]=laz[rc]=0;
     32         laz[id]=-1;
     33       }
     34   }
     35   void irt(int L,int R,int id,int x,int v)
     36   {
     37       if(L==R){
     38         sum[id]+=v;
     39         return;
     40       }
     41       pushdown(L,R,id);
     42       if(x<=M) irt(L,M,lc,x,v);
     43       else     irt(M+1,R,rc,x,v);
     44       pushup(L,R,id);
     45   }
     46   int change(int L,int R,int id,int l,int r)
     47   {
     48      if(L>=l&&R<=r){
     49         int res=sum[id];
     50         sum[id]=0;
     51         laz[id]=0;
     52         return res;
     53      }
     54      pushdown(L,R,id);
     55      int res=0;
     56      if(l<=M) res+=change(L,M,lc,l,r);
     57      if(r>M)  res+=change(M+1,R,rc,l,r);
     58      pushup(L,R,id);
     59      return res;
     60   }
     61   int ask1(int L,int R,int id,int x)
     62   {
     63       if(L==R) return P[L];
     64       pushdown(L,R,id);
     65       if(sum[lc]>=x){
     66         return ask1(L,M,lc,x);
     67       }
     68       else{
     69         return ask1(M+1,R,rc,x-sum[lc]);
     70       }
     71   }
     72   int ask2(int L,int R,int id,int x)
     73   {
     74       if(L==R) return sum[id];
     75       pushdown(L,R,id);
     76       if(x<=M) return ask2(L,M,lc,x);
     77       else if (x>M) return sum[lc]+ask2(M+1,R,rc,x);
     78   }
     79 
     80 }seg;
     81 int main()
     82 {
     83     //freopen("in.txt","r",stdin);
     84     int n,m,i,j,k;
     85     scanf("%d",&n); N=1;
     86     for(i=1;i<=n;++i)
     87     {
     88         scanf("%d%d",&a[i].opt,&a[i].x);
     89         x[i]=a[i].x;
     90     }
     91     sort(x+1,x+n+1);
     92     for(i=1;i<=n;++i)
     93     {
     94        if(x[i]==x[i-1]) continue;
     95        M1[x[i]]=++N;
     96        P[N]=x[i];
     97     }
     98     N++;
     99     seg.init();
    100     for(i=1;i<=n;++i)
    101     {
    102         int x1=M1[a[i].x];
    103         if(a[i].opt==1){
    104             seg.irt(1,N,1,x1,1);
    105         }
    106         else if(a[i].opt==2){
    107             seg.irt(1,N,1,x1,seg.change(1,N,1,1,x1-1));
    108         }
    109         else if(a[i].opt==3){
    110             seg.irt(1,N,1,x1,seg.change(1,N,1,x1+1,N));
    111         }
    112         else if(a[i].opt==4){
    113             printf("%d
    ",seg.ask1(1,N,1,a[i].x));
    114         }
    115         else if(a[i].opt==5){
    116             printf("%d
    ",seg.ask2(1,N,1,x1-1));
    117         }
    118     }
    119     return 0;
    120 }
  • 相关阅读:
    fiddler——异常退出以及session排序
    fiddler——设置断点,修改http响应
    fiddler——保存抓到的包(导出和导入)
    fiddler——session的操作
    基本套接字:套接字地址
    Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析
    用“DB查询分析器”的对象浏览器来展现数据库的数据字典
    基本套接字:UDP 客户端/服务器端
    信息编码:基本整型
    基本套接字:UDP 套接字
  • 原文地址:https://www.cnblogs.com/zzqc/p/7302477.html
Copyright © 2011-2022 走看看