小奇遐想
时间限制: 1 Sec 内存限制: 128 MB
提交: 236 解决: 41
[提交] [状态] [讨论版] [命题人:admin]
题目描述
撷来一缕清风飘渺
方知今日书信未到
窗外三月天霁垂柳新长枝条
风中鸟啼犹带欢笑
——《清风醉梦》
小奇望着青天中的悠悠白云,开始了无限的遐想,在它的视野中,恰好有n朵高度不同的白云排成一排,他想从左到右选出四朵白云a,b,c,d,使得h_a<h_b<h_d<h_c,即看起来像是彩虹的形状!它想知道有多少种方案数。
输入
第一行包括1个整数n。
第二行包括n个整数,第i个正数表示h_i,保证这n个整数是n的一个全排列。
输出
输出一个整数表示答案。(mod 16777216)
样例输入
5 1 5 3 2 4
样例输出
0
提示
对于10%的数据n<=600;对于40%的数据n<=5000;
对于100%的数据n<=200000。
一个树状数组的简单题,写一下题解来祭奠我WA30+。
首先观察四个数,控制第一个,后面三个难以控制,控制第四个,结果同第一个。发现控制第二个的时候,可以知道他前面有多少个比他小的数,然后数组是全排列,那么后面比他小的数的个数就是a[i]-pre_min-1,后面数的个数有n-i个,减去比他小的,剩下的数就是比他大的数,然后将前面比他小的跟后面比他大的相乘,其中会得到很多c>d的,那样的话取后面比他大的数的时候加一个排列,去除c>d这种情况,搞定。还有 C n 2不用求逆元,也不知道为什么脑卡的要去求一个非质数的逆元。
代码实现:感受下我的极限压行
/*
Look at the star
Look at the shine for U
*/
#include<bits/stdc++.h>
#define sl(x) scanf("%lld",&x)
using namespace std;
typedef long long ll;
const int N = 1e6+5;
const ll mod = 16777216;
const ll INF = 1e18;
ll s[N],c[N],ml[N],mr[N],T[N],n;
ll lowbit(ll k) {return k&(-k);}
void add(ll x,ll k,ll *t) {while(x <= n){t[x] = (t[x]+k);x += lowbit(x);}}
ll query(ll k,ll *t) {ll ans = 0;while(k){ans = (ans+t[k]); k -= lowbit(k);}return ans;}
int main()
{
ll i,j,k;
sl(n);
for(i = 1;i <= n;i++) sl(s[i]);
for(i = 1;i <= n;i++) {ml[i] = query(s[i],c);mr[i] = s[i]-ml[i]-1;add(s[i],1,c);}
ll sum1 = 0,sum2 = 0,x,y;
for(i = 1;i <= n;i++) sum1 = (sum1+ml[i]*(n-i-mr[i])*(n-i-mr[i]-1)/2)%mod;
for(i = 1;i <= n;i++) sum2 = (sum2+query(s[i],T)*(n-i-mr[i])%mod)%mod,add(s[i],ml[i],T);
ll ans = (sum1-sum2+mod)%mod;
printf("%lld\n",ans);
}