• BZOJ2141:排队


    浅谈分块:https://www.cnblogs.com/AKMer/p/10369816.html

    题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=2141

    第一次的答案可以直接用树状数组求。

    如果交换(pos_1)(pos_2),那么显然我不需要管([1,pos_1-1])([pos_2+1,n])

    对于([pos_1+1,pos_2-1])之间的每个数(v_i)

    (v_i<v_{pos_1}),答案减一;(v_i>v_{pos_1}),答案加一;(v_i<v_{pos_2}),答案加一,(v_i>v_{pos_2}),答案减一。

    对于每个块我用一个树状数组维护块内权值个数。整个的块直接查找有多少小于或者大于某个值的数的个数,零散的直接暴力扫。

    时间复杂度:(O(NlogN+Msqrt{N}logN))

    空间复杂度:(O(Nsqrt{n}))

    代码如下:

    #include <cmath>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define low(i) ((i)&(-(i)))
    
    const int maxn=2e4+5;
    
    int L[145],R[145];
    int n,m,cnt,block,ans;
    int tmp[maxn],v[maxn],bel[maxn];
    
    int read() {
    	int x=0,f=1;char ch=getchar();
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    	return x*f;
    }
    
    struct Tree_array {
    	int c[maxn];
    
    	void add(int pos,int num) {
    		for(int i=pos;i<=cnt;i+=low(i))
    			c[i]+=num;
    	}
    
    	int query(int pos) {
    		int res=0;
    		for(int i=pos;i;i-=low(i))
    			res+=c[i];
    		return res;
    	}
    }T[145];
    
    void check(int i,int l,int r) {
    	if(v[i]<v[l])ans--;
    	if(v[i]>v[l])ans++;
    	if(v[i]<v[r])ans++;
    	if(v[i]>v[r])ans--;
    }
    
    int main() {
    	n=read(),block=sqrt(n);
    	for(int i=1;i<=n;i++) {
    		v[i]=tmp[i]=read(),bel[i]=(i-1)/block+1;
    		if(bel[i]!=bel[i-1])R[bel[i-1]]=i-1,L[bel[i]]=i;
    	}R[bel[n]]=n;
    	sort(tmp+1,tmp+n+1);
    	cnt=unique(tmp+1,tmp+n+1)-tmp-1;
    	for(int i=1;i<=n;i++)
    		v[i]=lower_bound(tmp+1,tmp+cnt+1,v[i])-tmp;
    	for(int i=n;i;i--) {
    		ans+=T[0].query(v[i]-1);
    		T[0].add(v[i],1);
    		T[bel[i]].add(v[i],1);
    	}
    	printf("%d
    ",ans);
    	m=read();
    	while(m--) {
    		int l=read(),r=read();
    		if(r<l)swap(l,r);
    		if(bel[l]==bel[r]) {
    			for(int i=l+1;i<r;i++)
    				check(i,l,r);
    		}
    		else {
    			for(int i=l+1;i<=R[bel[l]];i++)
    				check(i,l,r);
    			for(int i=L[bel[r]];i<r;i++)
    				check(i,l,r);
    			for(int i=bel[l]+1;i<bel[r];i++) {
    				ans-=T[i].query(v[l]-1);
    				ans+=T[i].query(cnt)-T[i].query(v[l]);
    				ans+=T[i].query(v[r]-1);
    				ans-=T[i].query(cnt)-T[i].query(v[r]);
    			}
    			T[bel[l]].add(v[l],-1),T[bel[l]].add(v[r],1);
    			T[bel[r]].add(v[l],1),T[bel[r]].add(v[r],-1);
    		}
    		if(v[l]>v[r])ans--;
    		if(v[l]<v[r])ans++;
    		swap(v[l],v[r]);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    句柄实现SMARTFORMS
    SMARTFORMS错误整理:全局定义
    SAP Web IDE Local Trial Version的安装
    SAP 讲解史上最牛smartforms
    关于针对SMARTFORMS模板不能修改的解决办法
    特朗普赢了大选,中国赢了世界
    com.opensymphony.xwork2.ognl.OgnlValueStack]
    ognl.OgnlException: target is null for setProperty(null, "emailTypeNo", [Ljava.lang.String;@1513fd0)
    ASE Code Search
    ASE "黄金点游戏"
  • 原文地址:https://www.cnblogs.com/AKMer/p/10373414.html
Copyright © 2020-2023  润新知