• [HNOI2016]序列(未通过)


    题解:

    虽然知道有点问题但是并没有debug出来

    发现错误了。。相同元素的处理有错误

    网上题解大都是分块。。(hn怎么道道分块)

    用最普通的思路,可以枚举每个点作为最小值,向左向右延伸

    但是多组询问显然我们是要去优化询问过程的

    有一种方法就是先找出最大值

    (其实也可以是随意一个位置吧,但yy一下应该最大值能扩展的比较快)

    然后向两边分别找第一个比它小的值

    那么我们会发现,中间这一段元素他们一定是小于两边的值的

    也就是说,如果这两个点在区间里,中间的点也全部在区间里

    那么就可以用前缀和来预处理了

    当比它小的点已经超出边界的时候,显然是可以递归处理的

    查找最大值用倍增维护一下(线段树多了个log)

    时间复杂度在数据不随机的情况下大概会炸的

    并没有ac的代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 100100
    #define INF 1e9
    #define ll long long
    ll h,t,n,m;
    ll v[maxn],dp1[maxn],dp2[maxn],sum[maxn];
    struct re{
        ll h,t,pos,x;
    }p[maxn*4];
    struct ree{
       ll x1,x2; 
    }bz1[20][maxn];
    ll pd1(ll x,ll y)
    {
        if (v[x]>=v[y]) return(y);
        else return(pd1(x,dp1[y]));
    }
    ll pd2(ll x,ll y)
    {
        if (v[x]>=v[y]) return(y);
        else return(pd2(x,dp2[y]));
    }
    void updata(ll x)
    {
        p[x].x=max(p[x*2].x,p[x*2+1].x);
        if (p[x*2].x>p[x*2+1].x) 
          p[x].pos=p[x*2].pos;
        else p[x].pos=p[x*2+1].pos;
    }
    int query(int h,int t)
    {
        int x=log2(t-h+1),ans;
        ree a=bz1[x][h],b=bz1[x][t-(1<<x)+1];
        if (a.x1<b.x1) ans=b.x2; else ans=a.x2;
        return(ans); 
    }
    ll js(ll x,ll h,ll t)
    {
        return(v[x]*(min(dp2[x],t+1)-x)*(x-max(dp1[x],h-1)));
    }
    ll queryall(ll h,ll t)
    {
        if (h>t) return(0);
        ll ans=0,tmp,x;
        tmp=x=query(h,t);
        ans+=js(x,h,t);
        while (dp2[x]<=t)
        {
            ans+=sum[dp2[x]-1]-sum[x];
            x=dp2[x];
            ans+=js(x,h,t);
        }
        ans+=queryall(x+1,t); x=tmp;
        while (dp1[x]>=h)
        {
            ans+=sum[x-1]-sum[dp1[x]];
            x=dp1[x];
            ans+=js(x,h,t);
        }
        ans+=queryall(h,x-1);
        return(ans);
    }
    int main()
    {
        freopen("noip.in","r",stdin);
        freopen("noip.out","w",stdout);
        std::ios::sync_with_stdio(false);
        cin>>n>>m;
        v[0]=-INF; v[n+1]=-INF;
        for (ll i=1;i<=n;i++) cin>>v[i];
        for (ll i=1;i<=n;i++)
        {
            dp1[i]=pd1(i,i-1);
        }
        for (ll i=n;i>=1;i--)
        {
            dp2[i]=pd2(i,i+1);
        }
        for (int i=1;i<=n;i++) 
          bz1[0][i].x1=v[i],bz1[0][i].x2=i;
        for (int i=1;i<=20;i++)
          for (int j=1;j<=n;j++)
            if (j+(1<<i)-1<=n) 
              {
                  ree a=bz1[i-1][j],b=bz1[i-1][j+(1<<(i-1))];
                  if (a.x1>b.x1) bz1[i][j].x1=a.x1,bz1[i][j].x2=a.x2;
                  else bz1[i][j].x2=b.x1,bz1[i][j].x2=b.x2;
            }
        for (ll i=1;i<=n;i++)
        {
            sum[i]=
            sum[i-1]+(i-dp1[i])*(dp2[i]-i)*v[i];
        }
        for (ll i=1;i<=m;i++)
        {
            cin>>h>>t;
            cout<<queryall(h,t)<<endl;
        }
    }
  • 相关阅读:
    phpstrom中Terminal窗口打开
    window安装reidis完成之后,想要把数据存入redis,必须开扩展,不然报错,redis windows phpstudy 安装扩展
    Windows 安装 Anaconda3+PyCharm
    表单序列化+ajax跨域提交
    微信小程序无法获取到unionId(专业踩坑20年)
    支付宝的同步和异步的区别
    layui多图上传
    多图上传控制器及模型代码(2)thinkphp5+layui实现多图上传保存到数据库,可以实现图片自由排序,自由删除。
    【JZOJ4816】【NOIP2016提高A组五校联考4】label
    【JZOJ4815】【NOIP2016提高A组五校联考4】ksum
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8462295.html
Copyright © 2020-2023  润新知