若三个点 (x_1,y_1),(x_2,y_2),(x_3,y_3 ) 满足 x_1
若三个点 (x_1,y_1),(x_2,y_2),(x_3,y_3 ) 满足 x_1
5
1 5 3 2 4
3 4
这题乍一看水题,暴力O(n^2)好像可以过
仔细算就会发现,不行!!!
那我们就需要一种O(nlogn),甚至O(n)的算法
看“v”和“^”的满足条件有一些是不是很像线段树求逆序对呢
逆序对求法(线段树):逆序对
(其实我也不知道为什么,队测时自然想到线段树,没敢敲(吐血),错估了时间复杂度,以为是不如暴力的O(n^2logn))
还有一点,至少乘法原理你得想到吧,不知道的自己去学
先给暴力做法:
#include
int n,m,d[100001];long long ans1,ans2;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&d[i]);
for(int i=1;i<=n;i++)
{
int lx=0,rx=0,ll=0,rr=0;
for(int j=1;j
这个是最朴实无华的暴力了(TLE大法)
请看这句话(每个点的横、纵坐标的范围都是 1~N)
依据这个,可以小小优化暴力,下面给出暴力优化(并没有什么用,依然是TLE大法):
#include
int n,m,d[100001];long long ans1,ans2;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&d[i]);
for(int i=1;i<=n;i++)
{
int lx=0,ll=0;
for(int j=1;j
以上纯属娱乐,相信大家都会写
那个优化可有用,那么让我们来看正解吧
线段树(或树状数组)
#include
#include
using namespace std;
int n,ans1,ans2;long long ans0,ans;
struct oo{int a,b,v;}s[800001];
void build(int x,int l,int r)
{
s[x].a=l,s[x].b=r;
if(l==r)return ;
build(x<<1,l,l+r>>1);
build(x<<1|1,(l+r>>1)+1,r);
}
void change(int x,int y)
{
s[x].v++;
if(s[x].a==s[x].b)return ;
int mid=s[x].a+s[x].b>>1;
if(y<=mid)change(x<<1,y);
else change(x<<1|1,y);
}
void get(int x,int y)
{
if(y>s[x].b){ans1+=s[x].v;return ;}
if(y
很短吧!!
祝大家早日AC!!!