题目链接

洛谷P4559

题解

只会做\(70\)分的\(O(nlog^2n)\)

如果本来就在区间内的人是不用动的,区间右边的人往区间最右的那些空位跑,区间左边的人往区间最左的那些空位跑

找到这些空位就用二分 + 主席树

理应可以在主席树上的区间二分而做到\(O(nlogn)\),但是写不出来,先留着坑

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define REP(i,n) for (register int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,long long int>(a,b)
#define cp pair<int,long long int>
#define LL long long int
using namespace std;
const int maxn = 500005,maxm = 11000005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int N,n,m,rt[maxn];
int ls[maxm],rs[maxm],num[maxm],cnt;
LL sum[maxm];
void modify(int& u,int pre,int l,int r,int pos){
u = ++cnt;
sum[u] = sum[pre] + pos; num[u] = num[pre] + 1;
ls[u] = ls[pre]; rs[u] = rs[pre];
if (l == r) return;
int mid = l + r >> 1;
if (mid >= pos) modify(ls[u],ls[pre],l,mid,pos);
else modify(rs[u],rs[pre],mid + 1,r,pos);
}
int q_num(int u,int v,int l,int r,int L,int R){
if (l >= L && r <= R) return num[u] - num[v];
int mid = l + r >> 1;
if (mid >= R) return q_num(ls[u],ls[v],l,mid,L,R);
if (mid < L) return q_num(rs[u],rs[v],mid + 1,r,L,R);
return q_num(ls[u],ls[v],l,mid,L,R) + q_num(rs[u],rs[v],mid + 1,r,L,R);
}
LL q_sum(int u,int v,int l,int r,int L,int R){
if (l >= L && r <= R) return sum[u] - sum[v];
int mid = l + r >> 1;
if (mid >= R) return q_sum(ls[u],ls[v],l,mid,L,R);
if (mid < L) return q_sum(rs[u],rs[v],mid + 1,r,L,R);
return q_sum(ls[u],ls[v],l,mid,L,R) + q_sum(rs[u],rs[v],mid + 1,r,L,R);
}
inline LL S(int l,int r){
return 1ll * (l + r) * (r - l + 1) / 2;
}
inline LL q_pre(int u,int v,int L,int R,int k){
int ll = L,rr = R,mid; LL a;
while (ll < rr){
mid = ll + rr >> 1;
a = q_num(u,v,1,N,L,mid);
if ((mid - L + 1) - a >= k) rr = mid;
else ll = mid + 1;
}
a = q_sum(u,v,1,N,L,ll);
return S(L,ll) - a;
}
inline LL q_post(int u,int v,int L,int R,int k){
int ll = L,rr = R,mid,a;
while (ll < rr){
mid = ll + rr + 1 >> 1;
a = q_num(u,v,1,N,mid,R);
if ((R - mid + 1) - a >= k) ll = mid;
else rr = mid - 1;
}
a = q_sum(u,v,1,N,mid,R);
return S(ll,R) - a;
}
void work(){
int l,r,L,R,a,s; LL ans,b;
while (m--){
l = read(); r = read(); L = read(); R = L + r - l; ans = 0;
if (L > 1){
a = q_num(rt[r],rt[l - 1],1,N,1,L - 1);
if (a){
s = q_sum(rt[r],rt[l - 1],1,N,1,L - 1);
b = q_pre(rt[r],rt[l - 1],L,R,a);
ans += b - s;
}
}
a = q_num(rt[r],rt[l - 1],1,N,R + 1,N);
if (a){
s = q_sum(rt[r],rt[l - 1],1,N,R + 1,N);
b = q_post(rt[r],rt[l - 1],L,R,a);
ans += s - b;
}
printf("%lld\n",ans);
}
}
int main(){
n = read(); m = read(); N = 1000000 + n + 1; int x;
REP(i,n){
x = read(),modify(rt[i],rt[i - 1],1,N,x);
}
work();
return 0;
}

洛谷P4559 [JSOI2018]列队 【70分二分 + 主席树】的更多相关文章

  1. 洛谷P4559 [JSOI2018]列队(主席树)

    题面 传送门 题解 首先考虑一个贪心,我们把所有的人按\(a_i\)排个序,那么排序后的第一个人到\(k\),第二个人到\(k+1\),...,第\(i\)个人到\(k+i-1\),易证这样一定是最优 ...

  2. 洛谷P1979 华容道(70分 暴力)

    P1979 华容道 题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少 ...

  3. 洛谷P1081 开车旅行70分

    https://www.luogu.org/problem/show?pid=1081 太遗憾了明明写出来了,却把最小值初始值弄小了,从第二个点开始就不可能对了.70分! #include<io ...

  4. 2018.07.01洛谷P2617 Dynamic Rankings(带修主席树)

    P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i ...

  5. 洛谷P2633 Count on a tree(主席树,倍增LCA)

    洛谷题目传送门 题目大意 就是给你一棵树,每个点都有点权,每次任意询问两点间路径上点权第k小的值(强制在线). 思路分析 第k小......又是主席树了.但这次变成树了,无法直接维护前缀和. 又是树上 ...

  6. 【洛谷4587】 [FJOI2016]神秘数(主席树)

    传送门 BZOJ 然而是权限题 洛谷 Solution 发现题目给出的一些规律,emm,如果我们新凑出来的一个数,那么后面一个数一定是\(sum+1\). 于是就可以主席树随便维护了! 代码实现 #i ...

  7. 洛谷P2633 Count on a tree(主席树,倍增LCA,树上差分)

    洛谷题目传送门 题目大意 就是给你一棵树,每个点都有点权,每次任意询问两点间路径上点权第k小的值(强制在线). 思路分析 第k小......又是主席树了.但这次变成树了,无法直接维护前缀和. 又是树上 ...

  8. 洛谷P2633/bzoj2588 Count on a tree (主席树)

    洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...

  9. 【洛谷 P3899】 [湖南集训]谈笑风生 (主席树)

    题目链接 容易发现\(a,b,c\)肯定是在一条直链上的. 定义\(size(u)\)表示以\(u\)为根的子树大小(不包括\(u\)) 分两种情况, 1.\(b\)是\(a\)的祖先,对答案的贡献是 ...

随机推荐

  1. cocos2dx2.0 帧动画的创建和播放过程 深入分析

    一.帧动画的创建过程帧动画的实现有四个不可或缺的类,如下:1.CCSpriteFrame:精灵帧信息.存储帧动画的每一帧的纹理基本信息. class CC_DLL CCSpriteFrame : pu ...

  2. 使用idea写ssm的时候提示源文件夹中的文件找不到

    <context:property-placeholder location="classpath:db.properties"/>这一行idea提示找不到db.pro ...

  3. oss上传文件0字节

    最近使用oss上传文件,不同项目中使用的版本也不同,之前的都能正常上传,最近因需要添加ObjectMetaData属性,扩展了一个方法,发现上传的文件始终是0字节的,最终跟源码发现conntentLe ...

  4. MantisBT导出Excel文件名显示中文的修改方法

    我安装的是 mantisbt-2.15.0. 在“查看问题”页面导出Excel文件后,其文件名虽然是我选择的项目名称,但是,若项目名称中有中文,这就是用%加编码显示. 解决方法是: 在  <Ma ...

  5. SICP读书笔记 1.2

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

  6. python-创建进程的三种方式

    目录 1,os.fork() 方法 2,Process方法 3,Pool方法 1,os.fork() 方法 import os ret = os.fork() if ret == 0: #子进程 pr ...

  7. linux常用的查看设备的命令

    系统 # uname -a # 查看内核/操作系统/CPU信息  # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息  # ...

  8. WEB前端开发流程总结

    作者声明:本博客中所写的文章,都是博主自学过程的笔记,参考了很多的学习资料,学习资料和笔记会注明出处,所有的内容都以交流学习为主.有不正确的地方,欢迎批评指正 WEB前端开发项目流程总结 1.新建项目 ...

  9. Intense Heat(前缀和或尺取)

    The heat during the last few days has been really intense. Scientists from all over the Berland stud ...

  10. 第5题 查找字符串中的最长回文字符串---Manacher算法

    转载:https://www.felix021.com/blog/read.php?2040 首先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一 ...