「NOI考前欢乐赛」小奇遐想
撷来一缕清风飘渺
方知今日书信未到
窗外三月天霁垂柳新长枝条
风中鸟啼犹带欢笑
——《清风醉梦》
「问题描述」
小奇望着青天中的悠悠白云,开始了无限的遐想,在它的视野中,恰好有n朵高度不同的白云排成一排,他想从左到右选出四朵白云a,b,c,d,使得h_a < h_b < h_d < h_c,即看起来像是彩虹的形状!它想知道有多少种方案数。
「输入格式」
第一行包括1个整数n。
第二行包括n个整数,第 i 个正数表示h_i,保证这n个整数是n的一个全排列。
「输出格式」
输出一个整数表示答案。(mod 16777216)
「样例输入1」
5
1 5 3 2 4
「样例输出1」
0
「样例输入2」
4
1 2 4 3
「样例输出2」
1
「数据范围」
对于10%的数据n<=600;
对于40%的数据n<=5000;
对于100%的数据n<=200000。
这题是ctsc图腾弱化版。。。「数据结构练习」图腾
本来想给学弟出原题的,但是考虑原题太难
本题只需要求出1243个数
转化一下变成求12xx-1234
暴力n^3枚举2,1的个数预处理,43暴力
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; 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; } int n,ans; int a[200005],l[200005]; int main() { 	n=read(); 	for(int i=1;i<=n;i++)a[i]=read(); 	for(int i=1;i<=n;i++) 		for(int j=1;j<i;j++) 			if(a[j]<a[i])l[i]++; 	for(int a2=1;a2<=n;a2++) 		for(int a3=a2+1;a3<=n;a3++) 			if(a[a2]<a[a3]-1) 				for(int a4=a3+1;a4<=n;a4++) 					if(a[a2]<a[a4]&&a[a4]<a[a3]) 						ans=(ans+l[a2])&16777215; 	printf("%d\n",ans); 	return 0; } | 
正解是树状数组。。。
处理出每个数左边/右边比它小的个数
12xx就解决了
统计1234类似的再做一次树状数组,统计sigma l[j] (a[j]<a[i] j<i)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<map> #include<ctime> #include<vector> #include<set> #include<cmath> #include<algorithm> #define inf 1000000000 #define ll long long #define pa pair<int,int> #define P 16777215 using namespace std; 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; } int n,res; int a[200005]; ll l[200005],r[200005],t[200005]; void add(int x,int val) { 	for(int i=x;i<=n;i+=i&-i)t[i]+=val; } ll query(int x) { 	ll res=0; 	for(int i=x;i;i-=i&-i)res+=t[i]; 	return res; } void pre() { 	for(int i=1;i<=n;i++) 	{ 		l[i]=query(a[i]); 		r[i]=a[i]-l[i]-1; 		add(a[i],1); 	} } int cal1()//12xx { 	ll res=0; 	for(int i=1;i<=n;i++) 		res=(res+l[i]*(n-i-r[i])*(n-i-r[i]-1)/2)&P; 	return res; } int cal2()//1234 { 	memset(t,0,sizeof(t)); 	ll res=0; 	for(int i=1;i<=n;i++) 	{ 		res=(res+query(a[i])*(n-i-r[i]))&P; 		add(a[i],l[i]); 	} 	return res; } int main() { 	n=read(); 	for(int i=1;i<=n;i++)a[i]=read(); 	pre(); 	printf("%d",(cal1()-cal2())&P); 	return 0; } | 
                                  Subscribe  
                            
                                                                        
                    