HDOJ 5792 (2016多校联合训练 Training Contest 5) World is Exploding
2016-08-05 18:17
633 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5792
![](http://img.blog.csdn.net/20160805174613977)
题意,给我们n个数的序列A,问我们能够找到多少四个不同位置a,b,c,d的数满足:a≠b≠c≠d,1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ad.
这题很明显可以用到容斥原理去处理,我们可以先找到所有的情况然后我们再去减去多余的部分即可,算总个数显然就是所有的上升序列个数*所有的下降序列的个数。仔细思考,我们多余的是哪一部分的内容,很好想到,多处的部分就是我们只取了三个点的部分,所以我们需要减去的部分就是只选取了三个点又满足了含有上升序列和下降序列的即可。
对于求解的方法,我们可以统计每一位上的左边比它小的个数和,这个我们可以用到树状数组进行实现,而统计左边比它大的个数我们可以直接用到左边的总个数减去比它小的数的个数以及和它相等的个数。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const int maxn=5e4;
struct tnode{
int x,y;
}p[maxn+5];
int a[maxn+5],b[maxn+5];
int lmin[maxn+5],rmin[maxn+5];
int s1[maxn+5],s2[maxn+5];
bool cmp(tnode aa,tnode bb)
{
return aa.x<bb.x;
}
int query(int q[],int x)
{
int ans=0;
while(x>0)
{
ans+=q[x];
x-=(x&(-x));
}
return ans;
}
void add(int q[],int x,int k)
{
for(;x<=maxn;x+=(x&(-x)))b[x]+=k;
}
int main()
{
int n,i,j,k;LL ans,sum1,sum2;
while(~scanf("%d",&n))
{
for(i=1;i<=n;i++)scanf("%d",&p[i].x),p[i].y=i;
if(n<4)
{
printf("0\n");
continue;
}
sort(p+1,p+1+n,cmp);
k = a[p[1].y] = 1;
for(i=2; i<=n; i++)
if(p[i].x == p[i-1].x) a[p[i].y] = k;
else a[p[i].y] = (++k);
for(ms(s1,0),i=1; i<=n; i++) s1[a[i]]++;
for(ms(b,0),i=1; i<=n; i++)
lmin[i] = query(b,a[i]-1),add(b,a[i],1);
for(ms(b,0),i=n; i>=1; i--)
rmin[i] = query(b,a[i]-1),add(b,a[i],1);
sum1 = sum2 = 0;
for(i=1; i<=n; i++) sum1 += lmin[i],sum2 += rmin[i];
ans = sum1*sum2;
for(ms(s2,0),i=1;i<=n;i++)
{
ans -= lmin[i]*rmin[i];
ans -= (i-1-lmin[i]-s2[a[i]])*(n-i-rmin[i]-(s1[a[i]]-s2[a[i]]-1));
ans -= rmin[i]*(n-i-rmin[i]-(s1[a[i]]-s2[a[i]]-1));
ans -= lmin[i]*(i-1-lmin[i]-s2[a[i]]);
s2[a[i]]++;
}
printf("%I64d\n",ans);
}
return 0;
}
题意,给我们n个数的序列A,问我们能够找到多少四个不同位置a,b,c,d的数满足:a≠b≠c≠d,1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ad.
这题很明显可以用到容斥原理去处理,我们可以先找到所有的情况然后我们再去减去多余的部分即可,算总个数显然就是所有的上升序列个数*所有的下降序列的个数。仔细思考,我们多余的是哪一部分的内容,很好想到,多处的部分就是我们只取了三个点的部分,所以我们需要减去的部分就是只选取了三个点又满足了含有上升序列和下降序列的即可。
对于求解的方法,我们可以统计每一位上的左边比它小的个数和,这个我们可以用到树状数组进行实现,而统计左边比它大的个数我们可以直接用到左边的总个数减去比它小的数的个数以及和它相等的个数。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const int maxn=5e4;
struct tnode{
int x,y;
}p[maxn+5];
int a[maxn+5],b[maxn+5];
int lmin[maxn+5],rmin[maxn+5];
int s1[maxn+5],s2[maxn+5];
bool cmp(tnode aa,tnode bb)
{
return aa.x<bb.x;
}
int query(int q[],int x)
{
int ans=0;
while(x>0)
{
ans+=q[x];
x-=(x&(-x));
}
return ans;
}
void add(int q[],int x,int k)
{
for(;x<=maxn;x+=(x&(-x)))b[x]+=k;
}
int main()
{
int n,i,j,k;LL ans,sum1,sum2;
while(~scanf("%d",&n))
{
for(i=1;i<=n;i++)scanf("%d",&p[i].x),p[i].y=i;
if(n<4)
{
printf("0\n");
continue;
}
sort(p+1,p+1+n,cmp);
k = a[p[1].y] = 1;
for(i=2; i<=n; i++)
if(p[i].x == p[i-1].x) a[p[i].y] = k;
else a[p[i].y] = (++k);
for(ms(s1,0),i=1; i<=n; i++) s1[a[i]]++;
for(ms(b,0),i=1; i<=n; i++)
lmin[i] = query(b,a[i]-1),add(b,a[i],1);
for(ms(b,0),i=n; i>=1; i--)
rmin[i] = query(b,a[i]-1),add(b,a[i],1);
sum1 = sum2 = 0;
for(i=1; i<=n; i++) sum1 += lmin[i],sum2 += rmin[i];
ans = sum1*sum2;
for(ms(s2,0),i=1;i<=n;i++)
{
ans -= lmin[i]*rmin[i];
ans -= (i-1-lmin[i]-s2[a[i]])*(n-i-rmin[i]-(s1[a[i]]-s2[a[i]]-1));
ans -= rmin[i]*(n-i-rmin[i]-(s1[a[i]]-s2[a[i]]-1));
ans -= lmin[i]*(i-1-lmin[i]-s2[a[i]]);
s2[a[i]]++;
}
printf("%I64d\n",ans);
}
return 0;
}
相关文章推荐
- 极小化极大算法
- 文本处理工具-1
- select for update [nowait]
- VS2008:Failed to return new Code Element
- Could not find main method from given launch configuration
- coreseek错误WARNING: failed to open pid_file '/usr/local/coreseek/var/log/searchd_mysql.pid'
- No cache or cacheManager properties have been set. Authorization cache cannot be obtained.
- HDU 3537 Daizhenyang's Coin
- Lightoj1282——Leading and Trailing(幂取模求前三位)
- main函数的几种可行的写法
- 吐槽阿里云PAI
- AIDL学习
- cpu wait state --- cpu wait
- (译)关于async与await的FAQ
- 【入门介绍】机器学习之强化学习算法
- 利用RAID保护数据
- mail 发送邮件
- LeetCode Factorial Trailing Zeroes数学方法详解
- [AC自动机 fail树 树链的并] BZOJ 3881 [Coci2015]Divljak
- set explain on--Informix 11.5 SQL 语句性能监控方法及实现