魔导书

这里提出第三种(应该是)毒瘤做法

考虑我们把书标上等级,也就是 (b_i)

等级为 (b_i) 的书可以放在 (0-b_i) 这个区间中

那么我们直接贪心,先放大的再放小的,尽量的向右区间放置

直接用线段树维护哪些地方可以放就行了(坐稳最差解

#define __AVX__ 1
#define __AVX2__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE2_MATH__ 1
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1

#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")

#include <immintrin.h>
#include <emmintrin.h>

#include <cstdio>
#include <algorithm>

using namespace std;

struct point
{
  long long a,b;
}p[1000010];

struct segment
{
  int minid;
}tree[1000010<<2];

bool cmp(point a,point b)
{
  return a.a>b.a;
}

int n;

long long pl[1000010],ans;

void build(int u,int l,int r)
{
  tree[u].minid=r;
  if(l==r) return ;
  int mid=(l+r)>>1;
  build(u<<1,l,mid);
  build(u<<1|1,mid+1,r);
}

void change(int u,int l,int r,int p)
{
  if(l==r)
  {
    tree[u].minid=p;
    return ;
  }
  int mid=(l+r)>>1;
  if(p<=mid) change(u<<1,l,mid,p); 
  if(p>mid) change(u<<1|1,mid+1,r,p);
  if(pl[tree[u<<1].minid]<pl[tree[u<<1|1].minid]) tree[u].minid=tree[u<<1].minid;
  else tree[u].minid=tree[u<<1|1].minid;
}

int find(int u,int l,int r,int x,int y)
{
  if(x<=l&&r<=y) return tree[u].minid;
  int mid=(l+r)>>1,ans1=-10,ans2=-10;
  if(x<=mid) ans1=find(u<<1,l,mid,x,y); 
  if(y>mid) ans2=find(u<<1|1,mid+1,r,x,y);
  if(ans1==-10||ans2==-10) return max(ans1,ans2);
  if(pl[ans1]<pl[ans2]) return ans1;
  else return ans2;
}

int main()
{
  tree[1].minid=0;
  scanf("%d",&n);
  build(1,0,n);
  for(int i=1;i<=n;i++) scanf("%lld",&p[i].a),p[i].a;
  for(int i=1;i<=n;i++) scanf("%lld",&p[i].b),p[i].b;
  sort(p+1,p+n+1,cmp);
  for(int i=1;i<=n;i++)
  {
    int now=find(1,0,n,0,p[i].b);
    if(p[i].a>pl[now])
    {
      pl[now]=p[i].a;
      change(1,0,n,now);
    }
  }
  for(int i=0;i<=n;i++) ans+=pl[i];
  printf("%lld",ans%910666);
}
原文地址:https://www.cnblogs.com/zzqdeco/p/13657710.html