UPC5727小奇遐想【树状数组+容斥】

5727: 小奇遐想

时间限制: 1 Sec  内存限制: 128 MB
提交: 285  解决: 58
[提交] [状态] [讨论版] [命题人: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。

很简单,寻找1243这种序列直接找很难找到,所以需要容斥一下,即先找12xx这种序列只要XX都大于2即可,然后找到1234这种序列,那么用12xx-1234就是1243的答案。两遍树状数组查找。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define FIN freopen("D://code//in.txt", "r", stdin)
#define ppr(i,x,n) for(int i = x;i <= n;i++)
#define rpp(i,n,x) for(int i = n;i >= x;i--)
const double eps = 1e-8;
const int mod = 16777216;
const int maxn = 5e5+10;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;

inline int read() {//读入挂
    int ret = 0, c, f = 1;
    for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
    if(c == '-') f = -1, c = getchar();
    for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
    if(f < 0) ret = -ret;
    return ret;
}
ll front[maxn],back[maxn];//分别记录当前位置前面比他小的有多少个,后面比他大的有多好个 
ll a[maxn];
ll c[maxn];
ll n,ans1,ans2,ans;//ans1表示12xx个数ans2表示1234的个数最后ans=ans1-ans2为答案 
ll lowbit(ll x)
{
	return x&(-x);
}
ll sum(ll k)
{
	ll ans = 0;
	while(k > 0)
	{
		ans += c[k];
		k -= lowbit(k);
	}
	return ans;
}
void add(ll k,ll x)
{
	while(k <= n)
	{
		c[k] += x;
		k += lowbit(k);
	}
}

int main()
{
	IO;
	cin>>n;ans1=0;ans2=0;
	ppr(i,1,n) {cin>>a[i];front[i]=sum(a[i]);add(a[i],1);} 
	memset(c,0,sizeof(c));
	rpp(i,n,1) {back[i]=sum(n)-sum(a[i]);add(a[i],1);}
	//ppr(i,1,n) cout<<front[i]<<" "<<back[i]<<endl;
	ppr(i,1,n){ans1+=front[i]*(back[i]*(back[i]-1)/2);ans1%=mod;}
	memset(c,0,sizeof(c));
	ppr(i,1,n){ans2+=sum(a[i])*back[i];ans2%=mod;add(a[i],front[i]);}
    //cout<<ans1<<" "<<ans2<<endl;
	ans=(ans1-ans2+mod)%mod;
	cout<<ans<<endl;
	
}

猜你喜欢

转载自blog.csdn.net/Pandapan1997/article/details/81258582