写在前头
这题过了人挺多的,我从大根堆跑到二叉搜索树最后又打算二分,
结果都TLE(二分还没写)了,
给我搞的心态爆炸,结果题解竟然是树状数组,我真就哈哈哈哈哈
题意要求概括
就是给你一个数组,对于数组每次读入数,
你对当前这个数都要判断前面比他大的数的个数,和比他小的数的个数
树状数组模板
代码详解
```cpp
int getid(int x)
{
return lower_bound(g.begin(),g.end(),x)-g.begin()+1;
二分查找第一个比x大或等于的数 并返回该下标+1
}
int lowbit(int x)
{
return x&(-x);
}
void update(int x)
{
while(x<=n)
{
f[x]++;
x+= lowbit(x);
}
}
int query(int x)
{
int sum=0;
while(x)
{
sum+=f[x];
x-= lowbit(x);
}
return sum;
}
cin>>n;
for(int i=1; i<=n; i++)
scanf("%d",&a[i]),g.push_back(a[i]);
sort(g.begin(),g.end());
对原先的数组的值进行排序
for(int i=1; i<=n; i++)
b[i]=getid(a[i]);
b[i] 存的是 当前这个有多少个<=他自己的
int ans1=0,ans2=0;
for(int i=1; i<=n; i++)
{
if(i&1)
ans1=ans1+1+query(b[i])-(query(n)-query(b[i]));
else
ans2=ans2+1+query(b[i])-(query(n)-query(b[i]));
update(b[i]);
}
暴力做法
卧槽,原来暴力都可以
感谢我们的佬,教我计算这种时间复杂度,算出来正好是 5e9 又因为限制是2s稳过
int main()
{
long long int num1=0,num2=0;
int a,i,s[100005],sum,j;
cin>>a;
for(i=0; i<a; i++)
cin>>s[i];
for(i=0; i<a; i++)
{
sum=0;
for(j=0; j<i; j++)
{
if(s[i]>=s[j]) 找比他大的
sum++;
}
if(i%2==1)
num1+=1+sum-(i-sum);
else
num2+=1+sum-(i-sum);
}
if(num1==num2)
printf("hebei shuang king!");
else if(num1>num2)
printf("huaji is hebei king!");
else
printf("Calculus is hebei king!");
}
非暴力(二分+思维)
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n,a[100000],j=0,h=0;
cin>>n;
vector<long long>q;
for(long long i=0; i<n; i++)
{
long long num;
cin>>a[i];
long long sum=upper_bound(q.begin(),q.end(),a[i])-q.begin();
q.insert(q.begin()+sum,a[i]);
这里加一个Sum真的太666666666了 %%%%%%%%
num=i-sum;
if(i%2==0)
j+=1+sum-num;
else h+=1+sum-num;
}
if(j>h)
cout<<"Calculus is hebei king!";
else if(j<h)
cout<<"huaji is hebei king!";
else
cout<<"hebei shuang king!";
return 0;
}
总结
虽然说这次 我一直在纠结这题的数据结构虽然树状数组的确给我惊艳到了
但是 如果自己对这方面不怎么了解 更应该用思维去做题,可以说这次卡住了
没想到暴力做法也可以,这是我没想到的(时间复杂度还是不会计算)
同样地二分的这个**+sum**的思维可以说也不难
就是做少了