【BZOJ】【P3295】【CQOI2011】【动态逆序对】【题解】【树套树】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3295

用树状数组套平衡树统计逆序对,每加入一个数就统计在它前面比他大+在他后面比他大,可以离线,逆序加入数字,可以更快一点,

PS:线段树常数真心不能看……

Code:

#include<cstdio>
#include<climits>
#include<iostream>
#include<algorithm>
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define L i<<1
#define R i<<1|1
using namespace std;
const int maxn=1e5+10;
const int maxm=50010;
int n,m;
int a[maxn],b[maxm];
bool hash[maxn];
int rnd(){
	static int KEY=12345678;
	return KEY+=KEY<<2|1;
}
int getint(){
	int res=0,ok=0;char ch;
	while(1){
		ch=getchar();
		if(ch<='9'&&ch>='0'){
			res*=10;res+=ch-'0';ok=1;
		}else if(ok)break;
	}return res;
}
struct Treap{
	struct node{
		int val,key;
		int size;
		node *c[2];
		node(int _val,node *C){
			val=_val;key=rnd();
			c[0]=c[1]=C;size=1;
		}
		void rz(){
			size=c[0]->size+c[1]->size+1;
		}
	};
	node *root,*Null;
	Treap(){
		Null=new node(0,0);
		Null->size=0;Null->c[0]=Null->c[1]=Null;
		Null->key=INT_MAX;root=Null;
	}
	void rot(node *&t,bool d){
		node *p=t->c[d];
		t->c[d]=p->c[!d];
		p->c[!d]=t;
		t->rz();p->rz();
		t=p;
	}
	void _insert(node *&t,int x){
		if(t==Null){
			t=new node(x,Null);
			return ;
		}
		bool d=x>t->val;
		_insert(t->c[d],x);
		if(t->c[d]->key<t->key)
			rot(t,d);
		else 
			t->rz();
	}
	void _del(node *&t,int x){
		if(t->val==x){
			bool d=t->c[0]->key<t->c[1]->key;
			if(t->c[d]==Null){
				delete t;
				t=Null;
				return;
			}
			rot(t,d);
			_del(t->c[!d],x);
		}else{
			bool d=x>t->val;
			_del(t->c[d],x);
		}
		t->rz();
	}
	int _rank(node *&t,int x){
			if(t==Null)return 0;
		int r=t->c[0]->size;
		if(x==t->val)return r;
		if(x<t->val)return _rank(t->c[0],x);
		else return r+1+_rank(t->c[1],x);
	}
	void _deb(node *&t){
		printf("val:%d  size:%d\n",t->val,t->size);
		if(t->c[0]!=Null){
			printf("L: ");_deb(t->c[0]);
		}
		if(t->c[1]!=Null){
			printf("R: ");_deb(t->c[1]);
		}
	}
	void deb(){_deb(root);}
	void insert(int x){_insert(root,x);}
	void del(int x){_del(root,x);}
	int rank(int x){return _rank(root,x);}
	int size(){return root->size;}
};
Treap d[maxn];
int lowbit(int x){
	return x&(-x);
}
void updata(int x,int val){
	while(x<=n){
		d[x].insert(val);
		x+=lowbit(x);
	}
}
int get(int x,int val){
	if(x==0)return 0;
	int ans=0;
	while(x){
		ans+=d[x].rank(val);
		x-=lowbit(x);
	}
	return ans;
}
int size(int x){
	if(x==0)return 0;
	int ans=0;
	while(x){
		ans+=d[x].size();
		x-=lowbit(x);
	}
	return ans;
}
long long anss[maxm];
int p[maxn];
long long ans=0;
int main(){
//	freopen("1.txt","r",stdin);
//	freopen("3.txt","w",stdout);
	n=getint();m=getint();
	for(int i=1;i<=n;i++)a[i]=getint(),p[a[i]]=i;
	for(int i=1;i<=m;i++)b[i]=getint(),hash[b[i]]=1;
	
	for(int i=1;i<=n;i++){
		if(!hash[a[i]]){
			updata(i,a[i]);
			ans+=get(n,a[i])-get(i,a[i]);
			ans+=size(i-1)-get(i-1,a[i]);
			//T.Change(1,1,n,i,a[i]);	
			//ans+=T.Rank(1,1,n,i+1,n,a[i]);
			//ans+=T.size(1,1,n,1,i-1)-T.Rank(1,1,n,1,i-1,a[i]);
			//T.deb();
		}	
	}
	
	for(int i=m;i>=1;i--){
		
		
		updata(p[b[i]],b[i]);
		ans+=get(n,b[i])-get(p[b[i]],b[i]);
		ans+=size(p[b[i]]-1)-get(p[b[i]]-1,b[i]);
		//ans+=T.Rank(1,1,n,p[b[i]]+1,n,b[i]);
		//ans+=T.size(1,1,n,1,p[b[i]]-1)-T.Rank(1,1,n,1,p[b[i]]-1,b[i]);
		//T.deb();cout<<endl;
		anss[i]=ans;
	}
	for(int i=1;i<=m;i++)
		printf("%lld\n",anss[i]);
	
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值