「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