loj2051 「HNOI2016」序列

ref

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
int n, q, a[100005], l[100005], r[100005], sta[100005], din, blc, bel[100005], st[100005][19], mii[17], mlg[100005];
ll sl[100005], sr[100005], now, ans[100005];
struct Ques{
    int ll, rr, id;
}qu[100005];
bool cmp(Ques x, Ques y){
    if(bel[x.ll]!=bel[y.ll])    return bel[x.ll]<bel[y.ll];
    if(bel[x.ll]&1) return x.rr<y.rr;
    return x.rr>y.rr;
}
int getPos(int x, int y){
    int l=mlg[y-x+1], k=y+1-mii[l];
    return a[st[x][l]]<a[st[k][l]]?st[x][l]:st[k][l];
}
ll calL(int x, int y){
    int p=getPos(x, y);
    return (ll)a[p]*(y-p+1)+sr[x]-sr[p];
}
ll calR(int x, int y){
    int p=getPos(x, y);
    return (ll)a[p]*(p-x+1)+sl[y]-sl[p];
}
int main(){//freopen("sequence9.in", "r", stdin);
    cin>>n>>q;
    blc = sqrt(n);
    for(int i=1; i<=n; i++){
        scanf("%d", &a[i]);
        bel[i] = (i - 1) / blc + 1;
        st[i][0] = i;
    }
    for(int i=1; i<=q; i++){
        scanf("%d %d", &qu[i].ll, &qu[i].rr);
        qu[i].id = i;
    }
    sort(qu+1, qu+1+q, cmp);
    for(int i=1; i<=n; i++){
        while(din && a[sta[din]]>=a[i]) din--;
        if(din) l[i] = sta[din];
        sta[++din] = i;
    }
    din = 0;
    for(int i=n; i; i--){
        r[i] = n + 1;
        while(din && a[sta[din]]>=a[i]) din--;
        if(din) r[i] = sta[din];
        sta[++din] = i;
    }
    mii[0] = 1;
    for(int i=1; i<=16; i++)
        mii[i] = mii[i-1] << 1;
    for(int i=2; i<=n; i++)
        mlg[i] = mlg[i>>1] + 1;
    for(int j=1; j<=16; j++)
        for(int i=1; i<=n; i++){
            st[i][j] = st[i][j-1];
            int k=i+mii[j-1];
            if(k<=n)    st[i][j] = (a[st[i][j-1]]<a[st[k][j-1]])?st[i][j-1]:st[k][j-1];
        }
    for(int i=1; i<=n; i++)
        sl[i] = sl[l[i]] + (ll)(i - l[i]) * a[i];
    for(int i=n; i; i--)
        sr[i] = sr[r[i]] + (ll)(r[i] - i) * a[i];
    int gtl=qu[1].ll, zzh=gtl-1;
    for(int i=1; i<=q; i++){
        while(gtl>qu[i].ll) now += calL(--gtl, zzh);
        while(zzh<qu[i].rr) now += calR(gtl, ++zzh);
        while(gtl<qu[i].ll) now -= calL(gtl++, zzh);
        while(zzh>qu[i].rr) now -= calR(gtl, zzh--);
        ans[qu[i].id] = now;
    }
    for(int i=1; i<=q; i++)
        printf("%lld\n", ans[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/poorpool/p/8973546.html

时间: 2024-08-30 15:02:02

loj2051 「HNOI2016」序列的相关文章

AC日记——「SDOI2017」序列计数 LibreOJ 2002

「SDOI2017」序列计数 思路: 矩阵快速幂: 代码: #include <bits/stdc++.h> using namespace std; #define mod 20170408 #define ll long long struct MatrixType { int n,m; ll ai[105][105]; void mem(int n_,int m_) { n=n_,m=m_; for(int i=0;i<=n;i++) for(int v=0;v<=m;v++

LibreOJ #2002. 「SDOI2017」序列计数

二次联通门 : LibreOJ #2002. 「SDOI2017」序列计数 /* LibreOJ #2002. 「SDOI2017」序列计数 线性筛 + 矩阵优化dp 先构造出全部情况的矩阵 用矩阵快速幂计算答案 再构造出全不是质数的矩阵 计算出答案 前一个答案减后一个答案即可 */ #include <cstdio> #include <iostream> #include <cstring> const int BUF = 12312312; char Buf[BU

「JSOI2014」序列维护

「JSOI2014」序列维护 传送门 其实这题就是luogu的模板线段树2,之所以要发题解就是因为被 \(\color{black}{\text{M}} \color{red}{\text{_sea}}\) 告知了一种比较NB的 \(\text{update}\) 的方式. 我们可以把修改操作统一化,视为 \(ax + b\) 的形式,然后我们按照原来的套路来维护两个标记,分别代表 \(a\) 和 \(b\) ,那么我们的更新就可以这么写: inline void f(int p, int at

「LuoguP1430」 序列取数

题目描述 给定一个长为n的整数序列(n<=1000),由A和B轮流取数(A先取).每个人可从序列的左端或右端取若干个数(至少一个),但不能两端都取.所有数都被取走后,两人分别统计所取数的和作为各自的得分.假设A和B都足够聪明,都使自己得分尽量高,求A的最终得分. 输入输出格式 输入格式: 第一行,一个正整数T,表示有T组数据.(T<=100) 接着T行,每行第一个数为n,接着n个整数表示给定的序列. 输出格式: 输出T行,每行一个整数,表示A的得分 输入输出样例 输入样例#1: 复制 2 1

loj#2002. 「SDOI2017」序列计数(dp 矩阵乘法)

题意 题目链接 Sol 质数的限制并没有什么卵用,直接容斥一下:答案 = 忽略质数总的方案 - 没有质数的方案 那么直接dp,设\(f[i][j]\)表示到第i个位置,当前和为j的方案数 \(f[i + 1][(j + k) \% p] += f[i][j]\) 矩乘优化一下. #include<bits/stdc++.h> #define LL long long using namespace std; const int MAXN = 2e7 + 10, mod = 20170408,

「SDOI2015」序列统计

题目链接:Click here Solution: 容易得到这样一个\(dp\),设\(f[i][j]\)表示已经选了\(i\)个数,乘积\(mod \,\,m\)后为\(j\)的方案 \[ f[2\times i][j]=\sum_{a\times b\equiv j\,\,(mod\,\, m)} f[i][a]\times f[i][b] \] 考虑如何优化这个转移方程,注意到这道题的模数为\(1004535809\),这是一个很大的提示,考虑\(NTT\) 但是我们知道\(NTT\)处理

「luogu4462」[CQOI2018]异或序列

「luogu4462」[CQOI2018]异或序列 一句话题意 输入 \(n\) 个数,给定\(k\),共 \(m\) 组询问,输出第 \(i\) 组询问 \(l_i\) \(r_i\) 中有多少个连续子序列的异或和等于 \(k\).数据范围均在 \([0,1e5]\). 本题不强制在线,故莫队. 记序列 \(a\) 的前缀异或和 \(pre\),用一个桶 \(t_i\) 记录当前查询区间内前缀异或和为 \(i\) 的数量. 代码如下: #include <cstdio> #include &

大数据和「数据挖掘」是何关系?---来自知乎

知乎用户,互联网 244 人赞同 在我读数据挖掘方向研究生的时候:如果要描述数据量非常大,我们用Massive Data(海量数据)如果要描述数据非常多样,我们用Heterogeneous Data(异构数据)如果要描述数据既多样,又量大,我们用Massive Heterogeneous Data(海量异构数据)--如果要申请基金忽悠一笔钱,我们用Big Data(大数据) 编辑于 2014-02-2817 条评论感谢 收藏没有帮助举报作者保留权利 刘知远,NLPer 4 人赞同 我觉得 大数据

LOJ #2037. 「SHOI2015」脑洞治疗仪

#2037. 「SHOI2015」脑洞治疗仪 题目描述 曾经发明了自动刷题机的发明家 SHTSC 又公开了他的新发明:脑洞治疗仪——一种可以治疗他因为发明而日益增大的脑洞的神秘装置. 为了简单起见,我们将大脑视作一个 01 序列.1 代表这个位置的脑组织正常工作,0 代表这是一块脑洞. 1 0 1 0 0 0 1 1 1 0 脑洞治疗仪修补某一块脑洞的基本工作原理就是将另一块连续区域挖出,将其中正常工作的脑组织填补在这块脑洞中.(所以脑洞治疗仪是脑洞的治疗仪?) 例如,用上面第 8 号位置到第