http://acm.uestc.edu.cn/#/problem/show/1276
772002生病了!他觉得浑身难受,作为暴力界的致命人物,772002对于生病有着自己独特的认知与治疗方法.
772002治疗生病的方法就是去找一名叫人可木主的医生!当然请人可木主治疗的代价可不低!人可木主作为智商街上智商最高的人,他给人治疗的花费计算非常奇怪!人可木主会给病人一个{1,2,3,4}的排列t,之后他会通过玄学将病人的病症状况转换为一个N的排列,之后人可木主会询问病人这个N的排列中有多少对四元组( p[A1],p[A2],p[A3],p[A4] ) (A1<A2<A3<A4 )的大小关系与人可木主所给的4的排列t的大小关系相同。
当然,只有回答正确,人可木主才会医治病人。
恰逢情人节前后,学姐卿和Final潘都已经被妹纸约走了,浑身难受的772002又无法发挥出自己的暴力实力,只能把这个艰难的任务交给你了。
第一行一个整数N(1<=N<=2000)
第二行4 个整数A[1],A[2],A[3],A4
第三行n个整数,p[1],p[2],....,pn
输出仅一行,输出有多少A排列满足题意
5
1 2 3 4
1 2 3 4 5
5
做这道题你需要点出来的技能点是 树状数组
如果你会用树状数组求逆序数的个数的话,那么这道题也可以解决了,因为本质上就是求逆序数。
首先这道题怎么做呢?
总共有24种情况。
最智障的做法,就是把所有情况全部都讨论一下,都用两个树状数组去处理就好了,这个只要有耐心,慢慢写就好了。
但是智障还是会遇到2413这个顺序不会暴力,但是他灵机一动,发现2413 = 24xx-2431-2411-2433,然后容斥乱搞就好了,于是智障青年花了两个小时怼完了这道题。
一般青年说,这道题明显可以简化:
可以分三派:
1、1和4不连在一起,那么就n方枚举2和3的位置,剩下的1和4个数可以预处理算出来。
2、1和3不连在一起,类似1。
3、2和4不连在一起,把序列大小反过来,当成2做
然后2413用容斥做。
文艺青年说,这道题明显只用分成两种:2413和其他,2413用容斥做。
所以只用写一种就好了。
为什么呢?
让我们仔细想想,为什么一般青年的那3种情况可以做?
我们首先把平面切成3*3的小格子。
因为这些序列中存在(i,pi),(j,pj)两个点,使得每个格子内最多一个点
然后我们就暴力枚举这两个点,然后算部分和就好了。
于是就完了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2050;
int n;
int a[maxn];
int sum[maxn][maxn];
int signum(int x)
{
if(x==0)return 0;
if(x<0)return -1;
return 1;
}
int getsum(int x0,int x1,int y0,int y1)
{
x0++;
y0++;
return sum[x0][y0]-sum[x0][y1]-sum[x1][y0]+sum[x1][y1];
}
long long solve(int p[])
{
pair<int,int>temp;
if(abs(p[1]-p[3])!=1)
temp=make_pair(0,2);
else if(abs(p[0]-p[3])!=1)
temp=make_pair(1,2);
else if(abs(p[0]-p[2])!=1)
temp=make_pair(1,3);
else
temp=make_pair(1,2);
pair<int,int>p1;
p1=make_pair(p[temp.first],p[temp.second]);
int tmpSignum = signum(p1.first-p1.second);
long long ans = 0;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if(signum(a[i]-a[j])==tmpSignum)
{
int lower[4]={-1,-1,-1,-1};
int upper[4]={n,n,n,n};
lower[p1.first]=a[i],upper[p1.first]=a[i];
lower[p1.second]=a[j],upper[p1.second]=a[j];
for(int k=1;k<4;k++)
lower[k]=max(lower[k],lower[k-1]);
for(int k=2;k>=0;k--)
upper[k]=min(upper[k],upper[k+1]);
long long pro=1;
if(temp.first!=0)
{
int x = p[0];
pro*=getsum(-1,i,lower[x],upper[x]);
}
if(temp.first+1!=temp.second)
{
int x = p[temp.first+1];
pro*=getsum(i,j,lower[x],upper[x]);
}
if(temp.second!=3)
{
int x = p[3];
pro*=getsum(j,n,lower[x],upper[x]);
}
ans+=pro;
}
}
}
return ans;
}
int main()
{
scanf("%d",&n);
int p[4];
for(int i=0;i<4;i++)
scanf("%d",&p[i]),p[i]--;
for(int i=0;i<n;i++)
scanf("%d",&a[i]),a[i]--;
for(int i=0;i<n;i++)
sum[i][a[i]]++;
for(int i=n-1;i>=0;i--)
for(int j=n-1;j>=0;j--)
sum[i][j]+=sum[i+1][j]+sum[i][j+1]-sum[i+1][j+1];
long long ans = solve(p);
if(p[0]==1&&p[1]==3&&p[2]==0&&p[3]==2)
{
int p1[4]={2,3,0,1};
ans-=solve(p1);
}
else if(p[0]==2&&p[1]==0&&p[2]==3&&p[3]==1)
{
int p1[4]={1,0,3,2};
ans-=solve(p1);
}
cout<<ans<<endl;
}
#include <bits/stdc++.h>
#define lowbit(x) ((x)&(-x))
using namespace std;
const int maxn = 2000 + 15;
int n , a[5] , p[maxn] , lft[maxn] , rht[maxn] , ta , tb ;
void update(int * bit ,int x , int y) { while(x <= n){ bit[x] += y , x += lowbit(x);} }
int prefixsum(int * bit , int x) { int res = 0 ; while(x){ res += bit[x] , x-=lowbit(x);} return res;}
int query(int * bit , int l , int r) { return prefixsum( bit , r ) - prefixsum( bit , l - 1 ); }
long long solve_normal(){
long long res = 0;
int sign = a[1] < a[3];
for(int i = 1 ; i <= n ; ++ i){
memset( lft , 0 , sizeof( lft ) );
memset( rht , 0 , sizeof( rht ) );
for(int j = n ; j > i ; -- j) update( rht , p[j] , 1 );
for(int j = i + 1 ; j <= n ; ++ j){
update( rht , p[j] , -1 ); // Remove Element from Right
bool UpdateOperation = true;
if( ( p[i] < p[j] ) != sign ) UpdateOperation = false;
if(UpdateOperation){
if(a[2] < a[4]){
if( ta == 1 && tb == 3 ) res += query( lft , min(p[i],p[j]) + 1 , max(p[i],p[j]) - 1 ) * query( rht , max(p[i],p[j]) + 1 , n );
else if( ta == 2 && tb == 3 ) res += prefixsum( lft , min(p[i],p[j]) - 1 ) * query( rht , max(p[i],p[j]) + 1 , n );
else if( ta == 2 && tb == 4 ) res += prefixsum( lft , min(p[i],p[j]) - 1 ) * query( rht , min(p[i],p[j]) + 1 , max(p[i],p[j]) - 1 );
}else{
if( ta == 1 && tb == 3 ) res += query( lft , max(p[i],p[j]) + 1 , n ) * query( rht , min(p[i],p[j]) + 1 , max(p[i],p[j]) - 1 );
else if( ta == 2 && tb == 3 ) res += query( lft , max(p[i],p[j]) + 1 , n ) * prefixsum( rht , min(p[i],p[j]) - 1 );
else if( ta == 2 && tb == 4 ) res += query( lft , min(p[i],p[j]) + 1 , max(p[i],p[j]) - 1 ) * prefixsum( rht , min(p[i],p[j]) - 1 );
}
}
update( lft , p[j] , 1 ); // Add Element to Left;
}
}
return res;
}
long long solve_right(){
long long res = 0;
int sign = a[2] < a[4];
update( lft , p[1] , 1 );
for(int i = 2 ; i <= n ; ++ i){
memset( rht , 0 , sizeof( rht ) );
for(int j = i + 1 ; j <= n ; ++ j){
bool UpdateOperation = true;
if( ( p[i] < p[j] ) != sign ) UpdateOperation = false;
if(UpdateOperation){
if(a[1] < a[3]) res += prefixsum( lft , min(p[i],p[j]) - 1 ) * query( rht , max(p[i],p[j]) + 1 , n );
else res += query( lft , max(p[i],p[j]) + 1 , n ) * prefixsum( rht , min(p[i],p[j]) - 1 );
}
update( rht , p[j] , 1 );
}
update( lft , p[i] , 1 );
}
return res;
}
long long solve_special_2413(){
long long res = 0 ;
for(int i = 1 ; i <= n ; ++ i){
memset( rht , 0 , sizeof( rht ) );
memset( lft , 0 , sizeof( lft ) );
long long cur = 0 ;
for(int j = i + 1 ; j <= n ; ++ j) if(p[j] > p[i]) update( rht , p[j] , 1 );
for(int j = i + 1 ; j <= n ; ++ j){
bool UpdateOperation = true;
if( p[j] > p[i] ) UpdateOperation = false;
if( UpdateOperation ) res += cur;
else{
cur -= query( lft , p[j] + 1 , n );
update( rht , p[j] , -1 );
cur += prefixsum( rht , p[j] - 1 );
update( lft , p[j] , 1 );
}
}
}
return res;
}
long long solve_special_3142(){
long long res = 0 ;
for(int i = 1 ; i <= n ; ++ i){
memset( rht , 0 , sizeof( rht ) );
memset( lft , 0 , sizeof( lft ) );
long long cur = 0;
for(int j = i + 1 ; j <= n ; ++ j) if(p[j] < p[i]) update( rht , p[j] , 1 );
for(int j = i + 1 ; j <= n ; ++ j){
bool UpdateOperation = true;
if( p[j] < p[i] ) UpdateOperation = false;
if( UpdateOperation ) res += cur;
else{
cur -= prefixsum( lft , p[j] - 1 );
update( rht , p[j] , -1 );
cur += query( rht , p[j] + 1 , n );
update( lft , p[j] , 1 );
}
}
}
return res;
}
long long solve_mid(){
int sign = a[2] < a[3];
long long res = 0;
update( lft , p[1] , 1 );
for(int i = 2 ; i <= n ; ++ i){
memset( rht , 0 , sizeof( rht ) );
for(int j = i + 1 ; j <= n ; ++ j) update( rht , p[j] , 1 );
for(int j = i + 1 ; j <= n ; ++ j){
update( rht , p[j] , -1 );
bool UpdateOperation = true;
if( ( p[i] < p[j] ) != sign ) UpdateOperation = false;
if(UpdateOperation){
int l , r ;
if(a[1] < min( a[2] , a[3] )) l = prefixsum( lft , min( p[i] , p[j] ) - 1 );
else if(a[1] > max( a[2] , a[3] ) ) l = query( lft , max( p[i] , p[j] ) + 1 , n );
else l = query( lft , min( p[i] , p[j] ) + 1 , max( p[i] , p[j] ) - 1 );
if(a[4] < min( a[2] , a[3] )) r = prefixsum( rht , min( p[i] , p[j] ) - 1 );
else if(a[4] > max( a[2] , a[3] ) ) r = query( rht , max( p[i] , p[j] ) + 1 , n );
else r = query( rht , min( p[i] , p[j] ) + 1 , max( p[i] , p[j] ) - 1 );
res += 1LL * l * r ;
}
}
update( lft , p[i] , 1 );
}
return res;
}
int main(int argc,char *argv[]){
scanf("%d" ,&n);
for(int i = 1 ; i <= 4 ; ++ i) scanf("%d" , a + i);
for(int i = 1 ; i <= n ; ++ i) scanf("%d" , p + i);
int ID = a[1] * 1000 + a[2] * 100 + a[3] * 10 + a[4];
ta = min( a[1] , a[3] ) , tb = max( a[1] , a[3] );
long long ans = 0;
if( (ta == 1 && tb == 3) || (ta == 2 && tb == 3) || (ta == 2 && tb == 4) ) ans = solve_normal();
else if( ta == 1 && tb == 4 ) ans = solve_right();
else if(ID == 2413) ans = solve_special_2413();
else if(ID == 3142) ans = solve_special_3142();
else ans = solve_mid();
cout << ans << endl;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2050;
inline 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;
}
struct bit
{
int a[maxn];
void init()
{
memset(a,0,sizeof(a));
}
int lowbit(int x)
{
return x&(-x);
}
int query(int x)
{
int ans = 0;
for(int i=x;i;i-=lowbit(i))
ans+=a[i];
return ans;
}
void update(int x,int val)
{
for(int i=x;i<maxn;i+=lowbit(i))
a[i]+=val;
}
}L,R;
int n,a[maxn],p[maxn];
long long solve1234()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=n;j>i;j--)
{
R.update(a[j],1);
if(a[i]<a[j])
ans+=L.query(a[i]-1)*(R.query(2010)-R.query(a[j]));
}
}
return ans;
}
long long solve1243()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=i+1;j<=n;j++)
{
R.update(a[j],1);
if(a[i]<a[j])
ans+=L.query(a[i]-1)*(R.query(2010)-R.query(a[j]));
}
}
return ans;
}
long long solve1324()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=n;j>i;j--)
{
R.update(a[j],1);
if(a[i]>a[j])
ans+=L.query(a[j]-1)*(R.query(2010)-R.query(a[i]));
}
}
return ans;
}
long long solve1342()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=i+1;j<=n;j++)
{
R.update(a[j],1);
if(a[i]>a[j])
ans+=L.query(a[j]-1)*(R.query(2010)-R.query(a[i]));
}
}
return ans;
}
long long solve1423()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=n;j>i;j--)
{
R.update(a[j],1);
if(a[i]>a[j])
ans+=L.query(a[j]-1)*(R.query(a[i]-1)-R.query(a[j]));
}
}
return ans;
}
long long solve1432()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=i+1;j<=n;j++)
{
R.update(a[j],1);
if(a[i]>a[j])
ans+=L.query(a[j]-1)*(R.query(a[i])-R.query(a[j]));
}
}
return ans;
}
long long solve2134()
{
L.init(),R.init();
long long ans = 0;
for(int i=n;i>=1;i--)
{
L.update(a[i],1);
R.init();
for(int j=i-1;j>=1;j--)
{
R.update(a[j],1);
if(a[i]>a[j])
ans+=(L.query(2010)-L.query(a[i]))*R.query(a[j]-1);
}
}
return ans;
}
long long solve2143()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=i+1;j<=n;j++)
{
R.update(a[j],1);
if(a[j]>a[i])
ans+=(L.query(a[j]-1)-L.query(a[i]))*(R.query(2010)-R.query(a[j]));
}
}
return ans;
}
long long solve3241();
long long solve2314()
{
for(int i=1;i<=n;i++)
a[i]=n-a[i]+1;
return solve3241();
}
long long solve2341()
{
L.init(),R.init();
long long ans = 0;
for(int i=n;i>=1;i--)
{
L.update(a[i],1);
R.init();
for(int j=i-1;j>=1;j--)
{
R.update(a[j],1);
if(a[i]>a[j])
ans+=L.query(a[j]-1)*(R.query(a[i]-1)-R.query(a[j]));
}
}
return ans;
}
long long solve2431();
long long solve2413()//24xx-2431-2411-2433
{
L.init(),R.init();
long long ans = -solve2431();
for(int i=1;i<=n;i++)
{
R.init();
for(int j=n;j>i;j--)
{
R.update(a[j],1);
if(a[j]>a[i])
{
ans+=(R.query(a[j]-1)*(R.query(a[j]-1)-1))/2;
ans-=(R.query(a[i]-1)*(R.query(a[i]-1)-1))/2;
ans-=((R.query(a[j]-1)-R.query(a[i]))*((R.query(a[j]-1)-R.query(a[i]))-1))/2;
}
}
}
return ans;
}
long long solve2431()
{
L.init(),R.init();
long long ans = 0;
for(int i=n;i>=1;i--)
{
L.update(a[i],1);
R.init();
for(int j=i-1;j>=1;j--)
{
R.update(a[j],1);
if(a[j]<a[i])
ans+=L.query(a[j]-1)*(R.query(2010)-R.query(a[i]));
}
}
return ans;
}
long long solve3124()
{
L.init(),R.init();
long long ans = 0;
for(int i=n;i>=1;i--)
{
L.update(a[i],1);
R.init();
for(int j=i-1;j>=1;j--)
{
R.update(a[j],1);
if(a[i]<a[j])
ans+=(L.query(2010)-L.query(a[j]))*(R.query(a[i]-1));
}
}
return ans;
}
long long solve3142()
{
for(int i=1;i<=n;i++)
a[i]=n-a[i]+1;
return solve2413();
}
long long solve3214()
{
L.init(),R.init();
long long ans = 0;
for(int i=n;i>=1;i--)
{
L.update(a[i],1);
R.init();
for(int j=i-1;j>=1;j--)
{
R.update(a[j],1);
if(a[j]>a[i])
ans+=(L.query(2010)-L.query(a[j]))*(R.query(a[j]-1)-R.query(a[i]));
}
}
return ans;
}
long long solve3241()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=n;j>i;j--)
{
R.update(a[j],1);
if(a[j]>a[i])
ans+=(L.query(a[j]-1)-L.query(a[i]))*(R.query(a[i]-1));
}
}
return ans;
}
long long solve3412()
{
L.init(),R.init();
long long ans = 0;
for(int i=n;i>=1;i--)
{
L.update(a[i],1);
R.init();
for(int j=i-1;j>=1;j--)
{
R.update(a[j],1);
if(a[i]<a[j])
ans+=(L.query(a[j]-1)-L.query(a[i]))*(R.query(2010)-R.query(a[j]));
}
}
return ans;
}
long long solve3421()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=n;j>i;j--)
{
R.update(a[j],1);
if(a[i]>a[j])
ans+=(L.query(a[i]-1)-L.query(a[j]))*(R.query(a[j]-1));
}
}
return ans;
}
long long solve4123()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=i+1;j<=n;j++)
{
R.update(a[j],1);
if(a[j]>a[i])
ans+=(L.query(2010)-L.query(a[j]))*(R.query(a[j]-1)-R.query(a[i]));
}
}
return ans;
}
long long solve4132()
{
for(int i=1;i<=n;i++)
a[i]=n-a[i]+1;
return solve1423();
}
long long solve4213()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=i+1;j<=n;j++)
{
R.update(a[j],1);
if(a[j]>a[i])
ans+=(L.query(2010)-L.query(a[j]))*(R.query(a[i]-1));
}
}
return ans;
}
long long solve4231()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=n;j>i;j--)
{
R.update(a[j],1);
if(a[j]>a[i])
ans+=(L.query(2010)-L.query(a[j]))*(R.query(a[i]-1));
}
}
return ans;
}
long long solve4312()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=i+1;j<=n;j++)
{
R.update(a[j],1);
if(a[i]>a[j])
ans+=(L.query(2010)-L.query(a[i]))*R.query(a[j]-1);
}
}
return ans;
}
long long solve4321()
{
L.init(),R.init();
long long ans = 0;
for(int i=1;i<=n;i++)
{
L.update(a[i],1);
R.init();
for(int j=i+1;j<=n;j++)
{
R.update(a[j],1);
if(a[j]<a[i])
ans+=(L.query(2010)-L.query(a[i]))*(R.query(a[i]-1)-R.query(a[j]));
}
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=4;i++)
p[i]=read();
for(int i=1;i<=n;i++)
a[i]=read();
int id=p[1]*1000+p[2]*100+p[3]*10+p[4];
long long ans = 0;
if(id==1234)ans=solve1234();
if(id==1243)ans=solve1243();
if(id==1324)ans=solve1324();
if(id==1342)ans=solve1342();
if(id==1423)ans=solve1423();
if(id==1432)ans=solve1432();
if(id==2134)ans=solve2134();
if(id==2143)ans=solve2143();
if(id==2341)ans=solve2341();
if(id==2314)ans=solve2314();
if(id==2413)ans=solve2413();
if(id==2431)ans=solve2431();
if(id==3124)ans=solve3124();
if(id==3142)ans=solve3142();
if(id==3214)ans=solve3214();
if(id==3241)ans=solve3241();
if(id==3412)ans=solve3412();
if(id==3421)ans=solve3421();
if(id==4123)ans=solve4123();
if(id==4132)ans=solve4132();
if(id==4213)ans=solve4213();
if(id==4231)ans=solve4231();
if(id==4312)ans=solve4312();
if(id==4321)ans=solve4321();
printf("%lld\n",ans);
}