#BZOJ3744 GTY的妹子序列

 

Description

  我早已习惯你不在身边,
  人间四月天 寂寞断了弦。
  回望身后蓝天,
  跟再见说再见……
  某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现她们排成了一个序列,每个妹子有一个美丽度。
Bakser神犇与他打算研究一下这个妹子序列,于是Bakser神犇问道:"你知道区间[l,r]中妹子们美丽度的逆序对数吗?"
  蒟蒻Autumn只会离线乱搞啊……但是Bakser神犇说道:"强制在线。"
  请你帮助一下Autumn吧。
  给定一个正整数序列a,对于每次询问,输出al...ar中的逆序对数,强制在线。

Input

  第一行包括一个整数n(1<=n<=50000),表示数列a中的元素数。
  第二行包括n个整数a1...an(ai>0,保证ai在int内)。
  接下来一行包括一个整数m(1<=m<=50000),表示询问的个数。
  接下来m行,每行包括2个整数l、r(1<=l<=r<=n),表示询问al...ar中的逆序
  对数(若ai>aj且i<j,则为一个逆序对)。
l,r要分别异或上一次询问的答案(lastans),最开始时lastans=0。
  保证涉及的所有数在int内。

Output

  对每个询问,单独输出一行,表示al...ar中的逆序对数。

Sample Input

4   

1  4  2  3   

1   

2 4

Sample Output

2

求区间逆序对……

连修改都没有,水题!

我们记f[i][j]为i~j块的总逆序对数,处理散块的时候除了+另一端的贡献,记得把整块的贡献加上~

#include<bits/stdc++.h>
using namespace std;
const int N = 5e4+10,Maxsiz = 233;
#define Inc(i,L,r) for(register int i=(L);i<=(r);++i)
#define Red(i,r,L) for(register int i=(r);i>=(L);--i)
int n,Q,a[N];
int siz,bl[N];
int sum_bigger[Maxsiz][N];//1~i个块大于等于我的个数 
int sum_smaller[Maxsiz][N];//i~n个块小与等于的个数 
int f[Maxsiz][Maxsiz];//块与块的逆序对总个数 
struct SufFix{//后缀和 
	int c[N];
	#define lb(x) (x)&-(x)
	inline void add(int x,int k){
		for(;x>0;x-=lb(x))c[x]+=k;
	}
	inline int sum(int x){
		int ret=0;
		for(;x<=n;x+=lb(x))ret+=c[x];
		return ret;
	}
}sf;
inline void disc(){
	scanf("%d",&n);
	Inc(i,1,n)scanf("%d",&a[i]);
	int tmp[N];
	Inc(i,1,n)tmp[i]=a[i];
	sort(tmp+1,tmp+1+n);
	int len=unique(tmp+1,tmp+1+n)-tmp-1;
	Inc(i,1,n)a[i]=lower_bound(tmp+1,tmp+1+len,a[i])-tmp;
}
inline void init(){
	siz=sqrt(n);
	Inc(i,1,n)bl[i]=(i-1)/siz+1;
	//n√n 
	Inc(i,1,n)++sum_bigger[bl[i]][a[i]];
	Inc(i,1,bl[n]){
		Red(j,n,1)sum_bigger[i][j]+=sum_bigger[i][j+1];
		Red(j,n,1)sum_bigger[i][j]+=sum_bigger[i-1][j];
	}
	Inc(i,1,n)++sum_smaller[bl[i]][a[i]];
	Red(i,bl[n],1){
		Inc(j,1,n)sum_smaller[i][j]+=sum_smaller[i][j-1];
		Inc(j,1,n)sum_smaller[i][j]+=sum_smaller[i+1][j];
	}
	//n√nlogn
	Inc(i,1,bl[n]){
		memset(sf.c,0,sizeof(sf.c));
		int ret=0;
		Inc(j,i,bl[n]){
			Inc(k,1,siz){
				int idx=(j-1)*siz+k;
				if(idx>n)break;//防止越界
				ret+=sf.sum(a[idx]+1);
				sf.add(a[idx],1);
			}
			f[i][j]=ret;
		}
	}
}
int las_ans;
inline int Query(int L,int r){
	int ret=0;
	if(bl[r]-bl[L]<=1){
		Inc(i,L,r)ret+=sf.sum(a[i]+1),sf.add(a[i],1);
		Inc(i,L,r)sf.add(a[i],-1);
	}else {
		//左散块 √nlogn
		Inc(i,L,bl[L]*siz)ret+=sf.sum(a[i]+1),sf.add(a[i],1);//本身 
		Inc(i,L,bl[L]*siz)ret+=sum_smaller[bl[L]+1][a[i]-1]-sum_smaller[bl[r]][a[i]-1];//对整块区间的影响 
		//整块区间 1
		ret+=f[bl[L]+1][bl[r]-1];
		//右区间 √nlogn
		Inc(i,(bl[r]-1)*siz+1,r)ret+=sf.sum(a[i]+1),sf.add(a[i],1);//本身+左散块 
		Inc(i,(bl[r]-1)*siz+1,r)ret+=sum_bigger[bl[r]-1][a[i]+1]-sum_bigger[bl[L]][a[i]+1];//对整块的影响 
		//撤销 √nlogn
		Inc(i,L,bl[L]*siz)sf.add(a[i],-1);
		Inc(i,(bl[r]-1)*siz+1,r)sf.add(a[i],-1);
	}
	return las_ans=ret;
}
inline void solv(){
	memset(sf.c,0,sizeof(sf.c));
	scanf("%d",&Q);
	while(Q--){
		int L,r;scanf("%d%d",&L,&r);
		L^=las_ans,r^=las_ans;
		if(L>r)swap(L,r);
		cout<<Query(L,r)<<"\n";
	}
}
int main(){
	disc();
	init();
	solv();
	return 0;
}

 

 

 

### 回答1: bzoj作为一个计算机竞赛的在线评测系统,不仅可以提供大量的题目供程序员练习和学习,还可以帮助程序员提升算法和编程能力。为了更好地利用bzoj进行题目的学习和刷题,制定一个bzoj做题计划是非常有必要的。 首先,我们需要合理安排时间,每天留出一定的时间来做bzoj的题目。可以根据自己的时间安排,每天挑选适量的题目进行解答。可以先从难度较低的题目开始,逐渐提高难度,这样既能巩固基础知识,又能挑战自己的思维能力。 其次,要有一个计划和目标。可以规划一个每周或每月的题目数量目标,以及每个阶段要学习和掌握的算法知识点。可以根据bzoj的题目分类,如动态规划、图论、贪心算法等,结合自己的实际情况,有针对性地选择题目进行学习。 此外,要充分利用bzoj提供的资源。bzoj网站上有很多高质量的题解和优秀的解题代码,可以参考和学习。还有相关的讨论区,可以与其他程序员交流和讨论,共同进步。 最后,要坚持并保持思考。做题不是单纯为了刷数量,更重要的是学会思考和总结。遇到难题时,要有耐心,多思考,多尝试不同的解法。即使不能一次性解出来,也要学会思考和分析解题过程,以及可能出现的错误和优化。 总之,bzoj做题计划的关键在于合理安排时间、制定目标、利用资源、坚持思考。通过有计划的刷题,可以提高算法和编程能力,并培养解决问题的思维习惯,在计算机竞赛中取得更好的成绩。 ### 回答2: bzoj做题计划是指在bzoj这个在线测评系统上制定一套学习和刷题的计划,并且将计划记录在excel表格中。该计划主要包括以下几个方面的内容。 首先是学习目标的设定。通过分析自己的水平和知识缺口,可以设定一个合理的目标,比如每天解决一定数量的题目或者提高特定的算法掌握程度。 其次是题目选择的策略。在excel表格中可以记录下自己选择的题目编号、题目类型和难度等信息。可以根据题目的类型和难度来安排每天的刷题计划,确保自己可以逐步提高技巧和解题能力。 然后是学习进度的记录和管理。将每天的完成情况记录在excel表格中,可以清晰地看到自己的学习进度和任务完成情况。可以使用图表等功能来对学习进度进行可视化展示,更好地管理自己的学习计划。 同时,可以在excel表格的备注栏中记录下每道题目的解题思路、关键点和需要复习的知识点等信息。这样可以方便自己回顾和总结,巩固所学的知识。 最后,可以将excel表格与其他相关资料进行整合,比如算法教材、题目解析和学习笔记等。这样可以形成一个完整的学习档案,方便自己进行系统的学习和复习。 总之,bzoj做题计划excel的制定和记录可以帮助我们更加有条理和高效地进行学习和刷题。通过合理安排学习目标和题目选择策略,记录学习进度和思路,并整合其他学习资料,我们可以提高自己的解题能力,并在bzoj上取得更好的成绩。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值