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;
    }
    
  • 相关阅读:
    dN/dS与分子进化常用软件
    samtools和bcftools使用说明
    变异检测VarScan软件使用说明
    线程可以共享进程里的哪些资源
    函数调用与系统调用的区别
    海量数据统计出现次数
    海量数据查找问题
    建立高并发模型需要考虑的点
    言简意赅的TIME_WAIT
    常用的TCP选项
  • 原文地址:https://www.cnblogs.com/yiqiAtiya/p/14016851.html
Copyright © 2011-2022 走看看