LOJ 2551 「JSOI2018」列队——主席树+二分
题目:https://loj.ac/problem/2551
答案是排序后依次走到 K ~ K+r-l 。
想维护一个区间排序后的结果,使得可以在上面二分、求和;二分可以知道贡献是正还是负。
于是想用树套树维护一段区间的元素减去从0开始的等差数列的值。为了二分,维护 fr , sc 表示权值区间里第一个/最后一个权值。
时间空间都是 nlog2n 的,空间连 70 分的范围都开不下。而且对拍1000以内的数据还有错误,交上去 TLE 得只能得 70 分。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define ls Ls[cr]
#define rs Rs[cr]
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
int Mx(int a,int b){return a>b?a:b;}
int Mn(int a,int b){return a<b?a:b;}
ll Abs(ll x){if(x<)x=-x;return x;}
const int N=1e5+,M=N<<,M2=N*;
int n,m,qk,fx,a[N],tp[N],tot,Ls[M],Rs[M],rt[M];
struct Node{
int ct,fr,sc;ll sm;
Node(int c=,ll s=,int fr=N,int sc=)://fr:mn,sc:mx
ct(c),sm(s),fr(fr),sc(sc) {}
Node operator+ (const Node &b)const
{return Node(ct+b.ct,sm+b.sm,Mn(fr,b.fr),Mx(sc,b.sc));}
}I;
ll cal(int fx,int ct){return (ll)(*fx-ct+)*ct/;}
namespace G{
int tot,Ls[M2],Rs[M2]; Node vl[M2];
void ins(int l,int r,int &cr,int p,int k)
{
if(!cr){cr=++tot; vl[cr]=I;}
vl[cr].sm+=tp[k]; vl[cr].ct++;
vl[cr].fr=Mn(vl[cr].fr,k); vl[cr].sc=Mx(vl[cr].sc,k);
if(l==r)return; int mid=l+r>>;
if(p<=mid)ins(l,mid,ls,p,k);
else ins(mid+,r,rs,p,k);
}
Node qry(int l,int r,int cr,int L,int R)
{
if(!cr)return I; if(l>=L&&r<=R)return vl[cr];
int mid=l+r>>;
if(mid<L)return qry(mid+,r,rs,L,R);
if(R<=mid)return qry(l,mid,ls,L,R);
return qry(l,mid,ls,L,R)+qry(mid+,r,rs,L,R);
}
}
void build(int l,int r,int cr)
{
if(l==r)return; int mid=l+r>>;
ls=++tot; build(l,mid,ls);
rs=++tot; build(mid+,r,rs);
}
void ins(int l,int r,int cr,int p,int p2)
{
G::ins(,n,rt[cr],p2,p);
if(l==r)return; int mid=l+r>>;
if(p<=mid)ins(l,mid,ls,p,p2);
else ins(mid+,r,rs,p,p2);
}
ll qry(int l,int r,int cr,int L,int R)
{
Node d=G::qry(,n,rt[cr],L,R);
if(!d.ct)return ;
int fr=tp[d.fr]+fx, sc=tp[d.sc]+(fx-d.ct+);
if((fr>=qk&&sc>=qk)||(fr<=qk&&sc<=qk))
{
ll ret=d.sm+cal(fx,d.ct),tmp=(ll)d.ct*qk;
fx-=d.ct;
return Abs(ret-tmp);
}
int mid=l+r>>;
return qry(l,mid,ls,L,R)+qry(mid+,r,rs,L,R);
}
int main()
{
n=rdn();m=rdn();
for(int i=;i<=n;i++)a[i]=tp[i]=rdn();
sort(tp+,tp+n+); int lm=unique(tp+,tp+n+)-tp-;
tot=;build(,n,);
for(int i=;i<=n;i++)
{
a[i]=lower_bound(tp+,tp+lm+,a[i])-tp;
ins(,n,,a[i],i);
}
for(int i=,l,r;i<=m;i++)
{
l=rdn();r=rdn();qk=rdn(); fx=;
printf("%lld\n",qry(,n,,l,r));
}
return ;
}
看题解发现不用树套树,用主席树即可。
在主席树上二分,无法维护 fr , sc 表示权值区间里第一个/最后一个权值。
又看题解,发现可以维护区间里元素个数 ct,只要看看 ct[ ls ] 和 mid-K+1 哪个大,就知道该往哪边走。此时可以把另一个孩子里的元素都贡献给答案。
log(1e6)=20 ,但空间开 N*20 不够。开 N*21 可以。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define ls Ls[cr]
#define rs Rs[cr]
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
int Mx(int a,int b){return a>b?a:b;}
const int N=5e5+,M=N*;
int n,m,a[N],tp[N],mx,k,rt[N]; ll ans;
int tot,Ls[M],Rs[M],ct[M];ll sm[M];
ll cal(int x,int c){return (2ll*x+c-)*c/;}
void ins(int l,int r,int &cr,int pr,int p)
{
cr=++tot; ls=Ls[pr];rs=Rs[pr];
ct[cr]=ct[pr]+; sm[cr]=sm[pr]+p;
if(l==r)return; int mid=l+r>>;
if(p<=mid)ins(l,mid,ls,Ls[pr],p);
else ins(mid+,r,rs,Rs[pr],p);
}
void qry(int l,int r,int cr,int pr)
{
if(!(ct[cr]-ct[pr]))return;
if(l==r){ans+=abs(sm[cr]-k);return;}
int mid=l+r>>;
int lc=ct[ls]-ct[Ls[pr]],rc=ct[rs]-ct[Rs[pr]];
if(lc<=mid-k+)
{
ans+=sm[rs]-sm[Rs[pr]]-cal(k+lc,rc);
qry(l,mid,ls,Ls[pr]);
}
else
{
ans+=cal(k,lc)-sm[ls]+sm[Ls[pr]]; k+=lc;
qry(mid+,r,rs,Rs[pr]);
}
}
int main()
{
n=rdn();m=rdn();
for(int i=;i<=n;i++) a[i]=rdn(),mx=Mx(mx,a[i]);
for(int i=;i<=n;i++)
ins(,mx,rt[i],rt[i-],a[i]);
for(int i=,l,r;i<=m;i++)
{
l=rdn();r=rdn();k=rdn();
ans=; qry(,mx,rt[r],rt[l-]);
printf("%lld\n",ans);
}
return ;
}
LOJ 2551 「JSOI2018」列队——主席树+二分的更多相关文章
- 【LOJ】#2551. 「JSOI2018」列队
题解 老年选手一道裸的主席树都要看好久才看出来 首先熟练的把这个区间建成\(n\)个主席树 然后对于一个询问,我们相当于在主席树上二分一个mid,使得\(mid - K + 1\)正好和\([l,r] ...
- LOJ 2555 「CTSC2018」混合果汁——主席树
题目:https://loj.ac/problem/2555 二分答案,在可以选的果汁中,从价格最小的开始选. 按价格排序,每次可以选的就是一个前缀.对序列建主席树,以价格为角标,维护体积和.体积*价 ...
- loj#2255. 「SNOI2017」炸弹 线段树优化建图,拓扑,缩点
loj#2255. 「SNOI2017」炸弹 线段树优化建图,拓扑,缩点 链接 loj 思路 用交错关系建出图来,发现可以直接缩点,拓扑统计. 完了吗,不,瓶颈在于边数太多了,线段树优化建图. 细节 ...
- BZOJ.5319.[JSOI2018]军训列队(主席树)
LOJ BZOJ 洛谷 看错了,果然不是\(ZJOI\)..\(jry\)给\(JSOI\)出这么水的题做T3么= = 感觉说的有点乱,不要看我写的惹=-= 对于询问\(l,r,k\),设\(t=r- ...
- 2018.11.01 loj#2319. 「NOIP2017」列队(线段树)
传送门 唉突然回忆起去年去noipnoipnoip提高组试水然后省二滚粗的悲惨经历... 往事不堪回首. 所以说考场上真的有debuffdebuffdebuff啊!!!虽然当时我也不会权值线段树 这道 ...
- LOJ 2547 「JSOI2018」防御网络——思路+环DP
题目:https://loj.ac/problem/2547 一条树边 cr->v 会被计算 ( n-siz[v] ) * siz[v] 次.一条环边会被计算几次呢?于是去写了斯坦纳树. #in ...
- LOJ 2550 「JSOI2018」机器人——找规律+DP
题目:https://loj.ac/problem/2550 只会写20分的搜索…… #include<cstdio> #include<cstring> #include&l ...
- LOJ 2548 「JSOI2018」绝地反击 ——二分图匹配+网络流手动退流
题目:https://loj.ac/problem/2548 如果知道正多边形的顶点,就是二分答案.二分图匹配.于是写了个暴力枚举多边形顶点的,还很愚蠢地把第一个顶点枚举到 2*pi ,其实只要 \( ...
- LOJ 2546 「JSOI2018」潜入行动——树形DP
题目:https://loj.ac/problem/2546 dp[ i ][ j ][ 0/1 ][ 0/1 ] 表示 i 子树,用 j 个点,是否用 i , i 是否被覆盖. 注意 s1<= ...
随机推荐
- sklearn中树模型可视化的方法
在机器学习的过程中,我们常常会用到树模型的方式来解决我们的问题.在工业界,我们不仅要针对某个问题利用机器学习的方法来解决问题,而且还需要能力解释其中的原理或原因.今天主要在这里记录一下树模型是怎么做可 ...
- 自学python之路(day6)
一 函数的定义与调用 现在需要一个程序来实现len()的功能. 计算字符串 s 长度 s='好好学习' #函数的定义def my_len(): i = for k in s: i += print(i ...
- DFS和BFS
BFS 代码步骤: 1.写出每个点和每个点的邻接点的对应关系 2.方法参数:传一个对应关系和起始点 3.创建一个队列,然后每次都移除第一个,然后把移除的邻接点添加进去,打印取出的第一个,然后循环,一直 ...
- log4j:WARN Please initialize the log4j system properly解决办法
使用log4j,报警如下: log4j:WARN No appenders could be found for logger log4j:WARN Please initialize the log ...
- 剑指Offer (汇总)
刷完剑指Offer很久了,前几天想起来去年开通的博客园,正好把刷题笔记整理一下 刷题平台:牛客网 刷题语言:Python **链表(8道)** [剑指Offer 3. 从尾到头打印链表 (链表)](h ...
- nginx 带? rewrite 规则
由于需要重定向 url ,nginx需要rewrite .参考文献 http://huangqiqing123.iteye.com/blog/2083434 需求:将http://10.106.1.3 ...
- 3.13 练习题4:邮件发送(smtp)
3.13 练习题4:邮件发送(smtp) 前言本篇总结了QQ邮箱和163邮箱发送邮件,邮件包含html中文和附件,可以发给多个收件人,专治各种不行,总之看完这篇麻麻再也不用担心我的邮件收不到了.以下代 ...
- ELK 起航
ELK与我 我在2017年8月份第一次听说ELK并搭建了一次,当时看到KIBANA页面超级炫酷非常激动.现在已经过去了四个月了,现在的情况不像刚开始哪有无知了.现在是要应用到实际的项目中.首先说一下整 ...
- highchart在IE8下面的显示问题解决
完整的代码: <!DOCTYPE HTML><html> <head> <meta http-equiv="Content-Type" c ...
- centos6.5-VMware虚拟机-双网卡绑定
1 添加多张网卡(生产环境中有多个卡槽,可用ifconfig查看) 2 编辑两张虚拟机的网卡和物理机的连接方式,这里两张都使用NAT即可 3 打开虚拟机查看所有的网卡(网络接口),修改配置网卡配置文件 ...