zoukankan      html  css  js  c++  java
  • [NOIP2017]列队(树状数组)

    定义第i行为所有的点(i,j),0<j<m

    可以发现,每一行是相对独立的,每一次操作只会影响到当前行和最后一列

    考虑每一行和最后一列各开一个树状数组,但这样显然会爆空间

    实际上,对于没有离队过的点是没必要储存的,可以直接算出编号,

    因此只要用vector储存每一行和最后一列后加入的点即可

    还需要预处理一个数组d[i]表示第i次询问当前行的离队的点的纵坐标

    这个可以离线做出来,然后只需要对最后一列维护一个树状数组即可

    Code

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <cstring>
    #define ll long long
    #define lowbit(x) ((x)&(-x))
    #define N 300010
    using namespace std;
    
    struct info{int p,id;}A[N];
    int n,m,qn,mx,d[N],a[N<<1],q[N][2];
    vector<info> t[N];
    vector<ll>v[N],lst;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    void add(int x,int y){for(;x<=mx;x+=lowbit(x))a[x]+=y;}
    int Q(int x){
    	int r=0;for(;x;x-=lowbit(x))r+=a[x];
    	return r;
    }
    
    int Find(int R){
    	int tmp=0;
    	for(int l=0,r=mx;l<=r;){
    		int mid=(l+r)>>1;
    		if(Q(mid)>=R) tmp=mid,r=mid-1;
    		else l=mid+1;
    	}
    	return tmp;
    }
    
    void Init(){
    	n=read(),m=read(),qn=read(),mx=max(n,m)+qn;
    	for(int i=1;i<=qn;++i){
    		q[i][0]=read(),q[i][1]=read();
    		if(q[i][1]!=m) t[q[i][0]].push_back((info){q[i][1],i});
    	}
    	for(int i=1;i<=mx;++i) add(i,1);
    	for(int i=1;i<=n;++i){
    		for(info x:t[i]) add(d[x.id]=Find(x.p),-1);
    		for(info x:t[i]) add(d[x.id],1);
    	}
    }
    
    void solve(){
    	ll Ans;
    	for(int i=1;i<=qn;++i){
    		int x=Find(q[i][0]);
    		Ans=(x<=n)?(ll)x*m:lst[x-n-1];
    		add(x,-1);
    		if(q[i][1]!=m){
    			v[q[i][0]].push_back(Ans);
    			Ans=(d[i]<m)?(q[i][0]-1)*1ll*m+d[i]:v[q[i][0]][d[i]-m];
    		}
    		lst.push_back(Ans);
    		printf("%lld
    ",Ans);
    	}
    }
    
    int main(){Init();solve();}
    
  • 相关阅读:
    PAT1037:Magic Coupon
    PAT1081:Rational Sum
    PAT1039: Course List for Student
    PAT1069:The Black Hole of Numbers
    VC++中字符串编码处理的一些相关问题
    PAT1110:Complete Binary Tree
    Java编译器003---javac -d/-sourcepath/-classpath选项
    Java编译器002---javac -source/-target选项
    Java编译器001---javac -g选项
    力扣练习010---把字符串转换成整数
  • 原文地址:https://www.cnblogs.com/void-f/p/9345602.html
Copyright © 2011-2022 走看看