题目链接

洛谷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. 基于ejabberd实现各个客户端消息同步

    先上图再说(左侧是web端,右侧是ios端)              要实现上面的功能,如果所有设备都在线的话,那么carboncopy(xmpp xep-0280协议)这个模块是可以实现接收到的消 ...

  2. DNS递归查询与迭代查询

    注:一般TCP/IP的应用层或者OSI的会话.表示.应用层把数据称为数据或者信息,到了传输层把数据称为报文,到了最底层就是比特流了也就是字节流 DNS递归查询与迭代查询   基础知识 1.域名系统 2 ...

  3. IncDec序列:差分+贪心

    IncDec序列 题目描述: 给定一个长度为 n 的数列 a1,a2,…,an,每次可以选择一个区间[l,r],使下标在这个区间内的数都加一或者都减一. 求至少需要多少次操作才能使数列中的所有数都一样 ...

  4. hadoop Datanode Uuid unassigned

    在配置hadoop的hdfs的时候,要首先格式化,然后才能启动,但是格式化的方式有的是不对出现Initialization failed for Block pool <registering& ...

  5. 王者荣耀交流协会 -- 第4次Scrum会议

    Scrum master : 王磊 要求1 : 工作照片 照片由高远博同学拍摄 ,王露芝同学(外援)没有参加本次会议. 要求2 : 时间跨度:2017年10月16日 18:00 - 18:44 共计4 ...

  6. 欢迎来怼—第二次Scrum会议

    一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华小组照片 二.开会信息 时间:2017/10/14 18:30~18:47,总计17min.地点:东北师范 ...

  7. 关于算法的时间复杂度O(f(n))

    (一)算法时间复杂度定义: 在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级.算法的时间复杂度,也就是算法的时间量度,记作:T(n ...

  8. asp.net登录状态验证

    文章:ASP.NET 登录验证 文章:ASP.NET MVC下判断用户登录和授权状态方法 文章:.net学习笔记---HttpHandle与HttpModule 第一篇文章,介绍了 1)早期的Base ...

  9. lintcode-480-二叉树的所有路径

    480-二叉树的所有路径 给一棵二叉树,找出从根节点到叶子节点的所有路径. 您在真实的面试中是否遇到过这个题? Yes 样例 给出下面这棵二叉树: 所有根到叶子的路径为: [ "1-> ...

  10. caffe神经网络模型的绘图

    Python/draw_net.py, 这个文件,就是用来绘制网络模型的.也就是将网络模型由prototxt变成一张图片. 1.安装GraphViz # sudo apt-get install Gr ...