题目:

描述

给出长度为\(n\)的数组\(a\)和\(q\)个询问\(l,r\)。

求区间\([l,r]\)的所有子区间的前缀和的最大值之和;

范围:

$n \le 2 \times 10^5 , q \le 10^7 $;

数据给出的\(S,A,B,P\)参数随机生成,附加文件给出数据生成器;

保证任意一个连续子序列的最大前缀和不超过\(10^6\) ;

题解:

  • Part1

  • \([1,l-1]\)的\(a_{i}\)对区间\([l,r]\)的前缀和的大小是没用影响的,所以直接算答案就是;

\[记sum_{i} = \sum_{j=1}^{i}a_{i} \\
\begin{align} ans_{l,r} = \sum_{i=l}^{r}\sum_{j=i}^{r} max^{j}_{k=i}\{sum_{k}\} - \sum_{i=l-1}^{r-1} sum_{i}(r-i) \end{align}
\]

  • 考虑如何求区间连续子序列最大值之和;

  • \(kczno1\)的做法: https://loj.ac/article/489

  • 一个奇葩做法:

  • 对\(sum\)建出笛卡尔树,考虑一个节点的有效区间是\([l_{i},r_{i}]\);

  • 预先处理出每个点的贡献:\(s_{i} = (i - l_{i}+1) \ (r_{i} - i + 1)\) ;

  • 考虑直接求\(\sum_{i=l}^{r}s_{i}\)多算了什么,多算的部分其实就是\(l_{i}\)超出\(l\)或者\(r_{i}\)\(超出\)r​$的情况;

  • 记\(u为l的祖先且u>l,v为r的祖先且v<r , w = lca(l,r)\);

  • 多算的部分就是:$\sum_{u=l}^{u<w} (l-l_{u})(r_{u}-u+1) + \sum_{v=r}^{v>w} (r-r_{v})(v-l_{v}+1) $

  • 这个式子可以在笛卡尔的左树和右树上处理一下前缀;

  • 注意在\(w\)的时候(也就是区间最值的位置)\(u\)和\(v\)都会超出,特判一下即可;

  • Part2 \(\pm rmq\)

  • 标算需要一个\(O(1)\)的\(rmq\) ,(我没写这个,卡一卡常数也可以过的);

  • 区间最值问题可以通过笛卡尔树转化成\(lca\);

  • 注意到\(lca\)的\(rmq\)相邻的值相差为\(1或-1\)

  • 对序列分块令分块大小\(B = \frac{log \ n}{2}\),差分后\(2^B B^2\)处理所有本质不同的块的区间最值的位置;

  • 对\(\frac{n}{B}\)个块做\(rmq\), 整块直接\(O(1)\)查询rmq​$,散块调用预处理的块内最值;

  • 复杂度是:\(O(\sqrt{n}log^2n \ + \ n ) = O(n)\) ;

    #include <bits/stdc++.h>
    #define ll long long
    #define mod 998244353
    #define inf 1e18
    #define il inline
    #define rg register
    using namespace std;
    inline int R() {
    int rt = 0;
    char ch = getchar();
    bool isn = false;
    for (; ch < '0' || ch > '9'; ch = getchar()) isn = ch == '-' ? true : isn;
    for (; ch >= '0' && ch <= '9'; ch = getchar()) rt = rt * 10 + ch - '0';
    return isn ? -rt : rt;
    }
    const int N=2000010;
    ll a[2000007];
    int n, q, ans;
    int S, A, B, P, tp;
    long long lastans;
    inline int Rand() {
    S = (S * A % P + (B ^ (tp * lastans))) % P;
    S = S < 0 ? -S : S;
    return S;
    }
    int f[N][21],bin[21],rt,lg[N],le[N],ri[N],ls[N],rs[N];
    ll fl[N],Ls1[N],Ls2[N],fr[N],Rs1[N],Rs2[N];
    ll S1[N],S2[N],s[N];
    int sta[N],top;
    il int Max(int x,int y){
    if(a[x]==a[y])return x>y?x:y;
    return a[x]>a[y]?x:y;
    }//
    il int ask(int x,int y){
    int t = lg[y - x + 1];
    return Max(f[x][t], f[y-bin[t]+1][t]);
    }//
    il void dfs1(int k){
    le[k]=ri[k]=k;
    if(ls[k])dfs1(ls[k]),le[k]=le[ls[k]];
    if(rs[k])dfs1(rs[k]),ri[k]=ri[rs[k]];
    }
    il void dfs2(int k){
    s[k] = (ll)(k - le[k] + 1)*(ri[k] - k + 1)*a[k]; int t = fl[k] ; ll x = a[k]*(k-le[k]+1);
    Ls1[k] = Ls1[t] + x;
    Ls2[k] = Ls2[t] + x*ri[k];
    //
    t = fr[k]; x = a[k]*(ri[k]-k+1);
    Rs1[k] = Rs1[t] + x;
    Rs2[k] = Rs2[t] + x*le[k];
    //
    if(ls[k]){
    fr[ls[k]]=k;
    fl[ls[k]]=fl[k];
    dfs2(ls[k]);
    }
    if(rs[k]){
    fl[rs[k]]=k;
    fr[rs[k]]=fr[k];
    dfs2(rs[k]);
    }
    }//
    il void pre_solve(){
    for(rg int i=bin[0]=1;i<=20;++i)bin[i]=bin[i-1]<<1;
    for(rg int i=1;i<=n;++i){
    a[i] += a[i-1];
    S1[i] = S1[i-1] + a[i];
    S2[i] = S2[i-1] + a[i]*i;
    }
    lg[0]=-1;a[0]=-inf;
    for(rg int i=1;i<=n;++i)f[i][0]=i,lg[i]=lg[i>>1]+1;
    for(rg int i=1;i<=20;++i)
    for(rg int j=1;j+bin[i]-1<=n;++j){
    f[j][i] = Max(f[j][i-1], f[j+bin[i-1]][i-1]);
    }
    for(int i=1;i<=n;++i){
    while(top&&Max(sta[top],i)==i)ls[i]=sta[top--];
    if(top)rs[sta[top]]=i;
    sta[++top]=i;
    }
    rt = sta[1];
    dfs1(rt);
    dfs2(rt);
    for(rg int i=1;i<=n;++i)s[i]+=s[i-1];
    }//
    il ll cal1(int l,int r){
    l = max(2, l);
    return r * (S1[r-1] - S1[l-2]) - (S2[r-1] - S2[l-2]) ;
    }//
    il ll cal2(int l,int r){
    int t = ask(l,r);
    ll re = (s[r]-s[l-1]) - (ll)(t - le[t] + 1) * (ri[t] - t + 1) * a[t] + (ll)(t - l + 1) * (r - t + 1) * a[t] ;
    re -= l * (Rs1[l] - Rs1[t]) - (Rs2[l] - Rs2[t]);
    re -= (Ls2[r] - Ls2[t]) - r * (Ls1[r] - Ls1[t]);
    return re;
    }//
    il long long solve(int l, int r){
    return cal2(l, r)-cal1(l, r);
    }//
    int main() {
    freopen("cubelia.in", "r", stdin);
    freopen("cubelia.out", "w", stdout);
    n=R(),q=R();
    for(rg int i=1;i<=n;++i)a[i]=R();
    S=R(),A=R(),B=R(),P=R(),tp=R();
    pre_solve();
    for (;q;--q){
    int l=Rand()%n+1,r=Rand()%n+1;
    if (l>r)swap(l,r);
    lastans=solve(l,r);
    ans=(ans+lastans%mod)%mod;
    }
    cout<<(ans+mod)%mod<<endl;
    return 0;
    }//

【纪中集训2019.3.11】Cubelia的更多相关文章

  1. 【纪中集训2019.3.27】【集训队互测2018】小A的旅行(白)

    题目 描述 ​ \(0-n-1\)的图,满足\(n\)是\(2\)的整数次幂, $ i \to j $ 有 $ A_{i,j} $ 条路径: ​ 一条路径的愉悦值定义为起点和终点编号的\(and\)值 ...

  2. 【纪中集训2019.3.23】Deadline

    题意 描述 一个二分图\((A,B)\),每个点额外有一个颜色0或者1: 匹配时,只能相同颜色的点匹配: 给出\(A\)中的颜色,问如何分配\(B\)种的颜色使得\((A,B)\)的最大匹配最小: 范 ...

  3. 【纪中集训2019.3.12】Mas的仙人掌

    题意: ​ 给出一棵\(n\)个点的树,需要加\(m\)条边,每条边脱落的概率为\(p_{i}\) ,求加入的边在最后形成图中仅在一个简单环上的边数的期望: \(1 \le n \ , m \le 1 ...

  4. 【纪中集训2019.3.23】IOer

    题目 描述 你要在\(m\)天内,刷\(n\)道题,每天可以刷的题的数目不限: 第\(i\)天可以刷的题目的种类是\(ui+v\): 两种刷题的方案不同当且仅当某天刷题的数量不同或者依次刷题的种类不同 ...

  5. 【纪中集训2019.3.13】fft

    题意: 描述 一共有\(n+m\)道题,其中\(n\)道答案是\(A\),\(m\)道答案是\(B\): 你事先知道\(n和m\),问在最优情况下的期望答错次数,对\(998244353\)取模: 范 ...

  6. 【纪中集训2019.3.12】Z的礼物

    题意 已知\(a_{i} = \sum_{j=1}^{i} \{^{i} _{j} \}b_{j}\), 给出\(a_{1} 到 a_{n}\) : 求\(b_{l} 到 b_{r}\)在\(1e9+ ...

  7. 「中山纪中集训省选组D1T1」最大收益 贪心

    题目描述 给出\(N\)件单位时间任务,对于第\(i\)件任务,如果要完成该任务,需要占用\([S_i, T_i]\)间的某个时刻,且完成后会有\(V_i\)的收益.求最大收益. 澄清:一个时刻只能做 ...

  8. 纪中集训 Day 2

    今天(其实是昨天= =)早上起来发现好冷好冷啊= = 吃完饭就准备比赛了,好吧B组难度的题总有一道不知到怎么写QAQ 太弱了啊!!! 蒟蒻没人权啊QAQ 今天第4题不会写,在这里说说吧 题目的意思就是 ...

  9. 纪中集训 Day1

    今天早上起来吃饭,发现纪中伙食真的是太差了!!!什么都不热,早餐的面包还好,然后就迎来了美好的早晨= = 早上做一套题,T1T2果断秒,T3一看就是noi原题,还好看过题解会写,然后就愉快的码+Deb ...

随机推荐

  1. codeforces 1140E Palindrome-less Arrays

    题目链接:http://codeforces.com/contest/1140/problem/E 题目大意: 如果一个数组的存在一个奇数长的回文就不好. 不是不好的数组是好的. 你可以把-1用1到k ...

  2. 【转】git乱码解决方案汇总

    git乱码解决方案汇 2012-11-04更新:官方的“终极”解决方案:msysGit1.7.10开始使用UTF-8编码保存文件名. 2011-10-24更新: 从一篇链接到本篇文章的文章(我对这篇文 ...

  3. 《Spring1之第四次站立会议》

    <第四次站立会议> 昨天:我把小组成员找到的写关于登录界面的代码加到了我的项目工程里,并对它有了一定的了解,已经能够编译运行了,得到了登陆的界面: 今天:试着做了一下主框架里的在线人数的显 ...

  4. beta冲刺(5/7)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:恺琳 组员6:翟丹丹 组员7:何家伟 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4 ...

  5. alpha阶段总结 (第一阶段冲刺成果)

    首次接触手机APP的制作,虽然很多都不懂,但是在网上查阅相关知识和询问同学的帮助下,我们团队总算对此有相当的了解,但是因为时间问题,首次冲刺的成果不大,我们相信在下一次的冲刺中会给出更好的效果出来. ...

  6. 注册表:DWORD

    百度百科 DWORD全称Double Word,是指注册表的键值,每个word为2个字节的长度,DWORD 双字即为4个字节,每个字节是8位,共32位. 在键值项窗口空白处单击右键,选择“新建”菜单项 ...

  7. 结对项目-小学生四则运算系统(GUI)

    Coding克隆地址:https://git.coding.net/FrrLolix/CalGUI.git 伙伴博客:http://www.cnblogs.com/wangyy39/p/8763244 ...

  8. 路由器配置及IP设置及ping命令使用

    OSI的七层协议体系结构: 物理层.数据链路层.网络层.运输层.会话层.表示层.应用层 TCP/IP是一个四层的体系结构: 网络接口层.网际层(互联网层)(IP或ARP或ICMP).运输层(TCP或U ...

  9. vue 如何使用scss (转载)

    创建一个基于 webpack 模板的新项目 全局安装 vue-cli $ npm install --global vue-cli 创建一个基于 webpack 模板的新项目 $ vue init w ...

  10. php单例模式 (转

    假设我们需要写一个类用来操作数据库,并同时满足以下要求: ①SqlHelper类只能有一个实例(不能多)②SqlHelper类必须能够自行创建这个实例③必须自行向整个系统提供这个实例,换句话说:多个对 ...