BZOJ3932(主席树上二分+差分

按时间作为主席树的版本,每个版本的主席树都是一个权值线段树。

差分消去时间影响

对于当前时间版本的主席树查询前K大即可。

树上二分时结束后切记判定l==r的状态(易错

l==r叶子节点可能存在多个值(值大小为sum/siz )

用I64dOLE了好久 。。 。。。。 。 。。 。 。 。 。 。 。 。 。。 。

用bit/stdc++.h  CE.....

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 301500;
const int LOGN = 35;
const int maxn = N*LOGN;
#define lson son[rt][0]
#define rson son[rt][1]
#define un(x) (x>0?x:-x)
struct node{
    int pos,val;
};
node cf[N<<1];
ll sum[maxn],siz[maxn];
int son[maxn][2],root[N],id[N];
void pushup(int rt)
{
    siz[rt] = siz[lson]+siz[rson];
    sum[rt] = sum[lson]+sum[rson];
}
int tot = 0;
void update(int x,int& y,int l,int r,int p)
{
    y = ++tot;
    if(l==r)
    {
        if(p>0) siz[y] = siz[x]+1;
        else siz[y] = siz[x]-1;
        sum[y] = sum[x]+p;
        return ;
    }
    son[y][0] = son[x][0];
    son[y][1] = son[x][1];
    int m = (r+l)>>1;
    if(un(p)<=m) update(son[x][0],son[y][0],l,m,p);
    else update(son[x][1],son[y][1],m+1,r,p);
    pushup(y);

}
ll  bfind(int l,int r,int rt,int k)
{
    //cout<<"size:: "<<siz[rt]<<sum[rt]<<endl;
    if(siz[rt]<=k) return sum[rt];
    ll ans = 0;
    while(l<r)
    {
        int m = (r+l)>>1;
        if(k<siz[lson])
        {
            r = m;
            rt = lson;
        }
        else{
            l = m+1;
            k -= siz[lson];
            ans+=sum[lson];
            rt = rson;
        }
    }
    if(k&&siz[rt]>0) ans+=sum[rt]/siz[rt]*min(k,siz[rt]);
    return ans;
}
bool cmp(node a,node b)
{
    return a.pos<b.pos;
}
int main()
{
    int n,m;
    scanf("%d%d",&m,&n);
    int s,e,p;
    int lim = 0;
    int cnt = 0;
    for(int i=0;i<m;i++){
        scanf("%d%d%d",&s,&e,&p);
        cf[++cnt] = (node){s,p};
        cf[++cnt] = (node){e+1,-p};
        lim = max(lim,p);
    }
    sort(cf+1,cf+cnt+1,cmp);
    ll pre = 1;
    for(int i=1;i<=cnt;i++)update(root[i-1],root[i],1,lim,cf[i].val);
    for(int i=cnt;i>=1;i--){
        if(cf[i].pos!=cf[i+1].pos) id[cf[i].pos] = i;
    }
    for(int i=1;i<=n;i++){
        if(id[i]==0)id[i] = id[i-1];
        //cout<<id[i]<<endl;
    }
    int x,a,b,c,k;
    for(int i=0;i<n;i++)
    {
        scanf("%d%d%d%d",&x,&a,&b,&c);
        k = (a*pre+b)%c+1;
        pre = bfind(1,lim,root[id[x]],k);
        //cout<<x<<"  "<<id[x]<<" ";
        printf("%lld\n",pre);
    }
    return 0;
}

AC代码

时间: 2024-12-23 01:57:03

BZOJ3932(主席树上二分+差分的相关文章

洛谷P1083 借教室 二分 + 差分

洛谷P1083 借教室 二分 + 差分(或说前缀和,其实前缀和更准确一点) 首先二分答案,即取 mid 个人,且他们不会冲突 然后O(n) 判断是否冲突 如何判断呢,首先我们发现 一个人的操作相当于是将 一些连续的山削去了一个高度 然后我们可以记录这座山被消了多少高度,但这样一次就要 O(N) 总共(n^2) 但是我们发现高度差只有两个地方变了,一个是起始,一个是终止 t[ i ] 表示 h[ i ] - h[ i-1 ] 改变过后 于是 t[ s ]-=d,t[ t+1 ]+=d ; 然后这样

【BZOJ】4293: [PA2015]Siano 线段树上二分

[题意]给定n棵高度初始为0的草,每天每棵草会长高a[i],m次收割,每次在d[i]天将所有>b[i]的草收割到b[i],求每次收割量.n<=500000. [算法]线段树上二分 [题解]按照生长速度a[]排序后,容易发现数列永远单调. 在线段树上的区间维护以下值: 1.最后一棵草的高度a 2.上次收割日期b 3.总的草高和c 4.总的生长速度和d 5.收割标记D和B 上传的时候注意右区间收割晚于左区间时强制合并. 下传的时候注意标记D和B直接覆盖. 线段树上二分: 1.判断当前区间是否符合(

UVALive - 8086 Substring Sorting (后缀数组+线段树上二分)

题意: 给一个串S, 多次询问k和m,求S的所有长度为k的不同子串中,字典序为排第m的串的最早出现位置 简化问题: 如果没有长度k的限制,并且没有不同子串的限制要怎么做.要字典序第m大,容易想到用后缀数组,因为它就是将n个后缀按字典序排好的,设f(i) = 排名<=i的所有后缀的所有前缀的个数和,假设答案的串是排名i的后缀的前缀,那么有f(i) >= k 且 f(i-1) < k,则满足二分性,可以二分后缀排名解决. 扩展: 有不同子串的限制,则类似求一个串有多少不同子串那样,对于每个排

训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束)

layout: post title: 训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - BellmanFord - 图论 - 训练指南 - 差分约束 Halum UVA - 11478 题意 带权有向图,每个点都可以有如下操作:令从ta出发的每一条边增加d,终止于ta的每一条边减小d 最后让所有边权的最小值非负且尽量大 题

CF1083C Max Mex(线段树上二分)

这题卡倍增害我T了一发= = 显然Mex是可以二分的,于是就可以考虑二分一个Mex然后check一下 然后怎么check呢?可以对点权建一棵线段树,节点\([l,r]\)表示,链上点权的集合包括\([l,r]\)时,最短的链的端点 合并两个区间就是在四个端点间选两个作为新链的端点,判断另外两个端点在不在这条链上,在的话这就是一条合法的链.判断方法就是判断一下两段的距离是否等于一整条链的距离. 这样时间复杂度是\(O(nlog^2n)\),感觉可过的样子?然而还可以在线段树上二分把时间复杂度优化到

HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分)

HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分) 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6621 题意: 给你n个数,有m次询问 每次问你在区间[l,r]内 第k小的|\(a_i-p\)|是多少 题解: 主席树+二分 每次二分答案 如果p+mid到p-mid的值的个数大于k个的话,mid值就是可行了,然后缩小区间往左找即可 因为保证有解,所以二分出来的mid值就是答案了 que

【BZOJ3932】任务查询系统,主席树与差分的建树思想

Time:2016.05.08 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: 说真的我一开始做这个题真不知道怎么建树,只知道应该以时间为根建树,记录优先值并维护前缀和,但想不出怎么用到主席树的前缀建树思想,暴力建树+修改肯定是不科学的-- 后来去看题解,发现又是差分. 回想起被运输计划支配的恐惧--(还是自己太弱的缘故) 不过这个差分比较简单,因为它正好利用了第i棵主席树以第i-1棵树为基础建树的思路,比如某一任务的时间区间为[l,r],优先度为p,那么我们在root[l]上

BZOJ 4326:NOIP2015 运输计划(二分+差分+lca)

NOIP2015 运输计划Description公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家物流公司, 该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 ui 号星球沿最快的宇航路径飞行到 vi 号星球去.显然,飞船驶过一条航道是需要时间的,对于航道 j,任意飞船驶过它所花费的时间为 tj,并且任意两艘飞船之间不会产生任何干扰.为了鼓励科技创新, L

13年山东省赛 Boring Counting(离线树状数组or主席树+二分or划分树+二分)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 2224: Boring Counting Time Limit: 3 Sec  Memory Limit: 128 MB Description In this problem you are given a number sequence P consisting of N integer and Pi is the ith element in the sequence.