zoukankan      html  css  js  c++  java
  • P3285 [SCOI2014]方伯伯的OJ

    链接

    因为 (n leq 10^8)(m leq 10^5),所以可以用一个域很大的权值线段树动态开点维护。

    开始 (L=1)(R=n)([L,R]) 的点值看作 (1),把一个位置的数提前相当于 (L-1) 的位置加 (1),原来的位置 (1) 变为 (0),放后也类似。

    用两个 (map) 维护数的位置和编号的相互映射。

    #include<bits/stdc++.h>
    #define IL inline
    #define LL long long
    using namespace std;
    const int N=1e5+3,inf=1e8+1e5+10;
    int n,m,ans,L,R,rt;
    map<int,int>mp1,mp2;
    IL int in(){
      char c;int f=1;
      while((c=getchar())<'0'||c>'9')
        if(c=='-') f=-1;
      int x=c-'0';
      while((c=getchar())>='0'&&c<='9')
        x=x*10+c-'0';
      return x*f;
    }
    struct hh{
      int cnt,ls[N*400],rs[N*400],sum[N*400];
      void upd(int &o,int l,int r,int u){
    	  if(!o) o=++cnt;++sum[o];
    		if(l==r) return;
    	  int mid=l+r>>1;
    	  if(u<=mid) upd(ls[o],l,mid,u);
    	  else upd(rs[o],mid+1,r,u);
    	}
    	int ask(int o,int l,int r,int rr){
    	  if(!o) return 0;
    	  if(r<=rr) return sum[o];
    	  int mid=l+r>>1;
    	  if(rr<=mid) return ask(ls[o],l,mid,rr);
    	  return ask(ls[o],l,mid,rr)+ask(rs[o],mid+1,r,rr);
    	}
    	int kth(int o,int l,int r,int k){
    	  if(l==r) return l;
    	  int mid=l+r>>1,res=max(0,min(R,mid)-max(L,l)+1)-sum[ls[o]];
    	  if(res>=k) return kth(ls[o],l,mid,k);
    	  return kth(rs[o],mid+1,r,k-res);
    	}
    }T;
    int query(int x){
      if(mp1.find(x)!=mp1.end()) x=mp1[x];
    	return x-L-T.ask(rt,-inf,inf,x-1)+1;
    }
    void work1(int x,int y){
      if(mp1.find(x)!=mp1.end()) mp2[mp1[x]]=y,mp1[y]=mp1[x];
      else mp2[x]=y,mp1[y]=x;
      printf("%d
    ",ans=query(y));
    }
    void work2(int x){
    	printf("%d
    ",ans=query(x));int y=x;
      if(mp1.find(x)!=mp1.end()) x=mp1[x];
      T.upd(rt,-inf,inf,x),mp1[y]=--L,mp2[L]=y;
    }
    void work3(int x){
    	printf("%d
    ",ans=query(x));int y=x;
      if(mp1.find(x)!=mp1.end()) x=mp1[x];
      T.upd(rt,-inf,inf,x),mp1[y]=++R,mp2[R]=y;
    }
    void work4(int k){
      int x=T.kth(rt,-inf,inf,k);
      if(mp2.find(x)!=mp2.end()) printf("%d
    ",ans=mp2[x]);
      else printf("%d
    ",ans=x);
    }
    int main()
    {
    	int op,x,y;
    	n=in(),m=in(),L=1,R=n;
    	for(int i=1;i<=m;++i){
    	  op=in(),x=in()-ans;
    	  if(op==1) work1(x,in()-ans);
    	  else if(op==2) work2(x);
    	  else if(op==3) work3(x);
    	  else work4(x);
    	}
      return 0;
    }
    
  • 相关阅读:
    frame框架 超链接
    SQL与ASP日期时间
    J2EE开发环境搭建(3)——保存你搭建好的J2EE开发环境
    td.moveRow方法
    SQL Management Studio Express 安装缺少MSXML6解决
    js tr onmouseover时改变该行背景色
    doc 解决windows系统中名字为eula的文件无法被删除
    js select 隐藏option
    LLBLGen的数据库相对应SQL语句实现方法收藏
    使用 DataAdapter 更新数据源
  • 原文地址:https://www.cnblogs.com/yiqiAtiya/p/14016851.html
Copyright © 2011-2022 走看看