首页 > 其他分享 >2022NOIPA层联测33

2022NOIPA层联测33

时间:2022-11-22 20:55:39浏览次数:86  
标签:ch 2022NOIPA 33 ll long int maxn 联测 序列

C. 建筑

鹤了才发现我的50pts部分分居然和正解很沾边!!

感觉所有序列上说什么用笛卡尔树的东西都可以用单调栈代替,比如《矩形》

50% code
/*
二缺吧我是,调了俩小时才发现系数和最值一一对应只能单点查询!?
真是醉了还是n^4的。。。
*/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 204;

int n, m, v[maxn][maxn], Mx[maxn][maxn][maxn];
int st[maxn], top;
ll ans, res1, res2, sum[maxn][maxn][maxn];

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}

struct line 
{
    struct lines 
    {
        ll mx, xs;
    }t[maxn];
    void clear(int n)
    {
        for(int i=1; i<=n; i++)
        {
            t[i].mx = t[i].xs = 0;
        }
    }
    void update1(int l, int r, int v)
    {
        for(int i=l; i<=r; i++) t[i].mx = v;
    }
    void update2(int l, int r, int v)
    {
        for(int i=l; i<=r; i++) t[i].xs++;
    }
    int query(int l, int r)
    {
        int ans = 0;
        for(int i=l; i<=r; i++) ans += t[i].mx*t[i].xs;
        return ans;
    }
}t;

int main()
{
    freopen("building.in", "r", stdin);
    freopen("building.out", "w", stdout);
    
    n = read(), m = read();
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++) v[i][j] = read();
    }
    for(int i=1; i<=n; i++)
    {
        for(int l=1; l<=m; l++)
        {
            int su = 0, ma = 0;
            for(int r=l; r<=m; r++)
            {
                su += v[i][r]; ma = max(ma, v[i][r]);
                sum[i][l][r] = su, Mx[i][l][r] = ma;
            }
        }
    }
    for(int l=1; l<=m; l++)
    {
        for(int r=l; r<=m; r++)
        {
            top = 0; res1 = 0; res2 = 0;
            t.clear(n);
            for(int i=1; i<=n; i++)
            {
                while(top && Mx[st[top]][l][r] < Mx[i][l][r]) top--;
                t.update1(st[top]+1, i, Mx[i][l][r]);
                st[++top] = i;
                t.update2(1, i, 1);
                res1 += t.query(1, i);
            }
            res1 *= (r-l+1);
            for(int i=1; i<=n; i++)
            {
                res2 += sum[i][l][r]*(n-i+1)*i;
            }
            ans += res1-res2;
        }
    }
    printf("%lld\n", ans);

    return 0;
}

差别在于:没有考虑根号,保持了矩阵的原有形态,比较T;把矩形压成序列不需要过度预处理,空间开不下;但是最主要的是我并不知道怎么O(n)算出序列的答案(应该是最重要的部分)。

本来想把最大值的系数鹤最大值自己拆开,放到线段树上变成互不干涉的两部分,然而它们的一一对应关系是不可能解除的,由于单点查询代表复杂度不可避免,我把它改成了暴力处理。

然而最终死于没开long long——连续的第二天!!

前两天《串串超人》刚刚提醒过我们:只需要求和的东西不需要维护序列,这个题也是这样的。如果只是最大值求和就很显然,加上的区间长度也不难算,发现这些区间长度构成了等差序列,所以要用到等差序列求和公式。

ll calc(ll x, ll y) {return (x+y)*(y-x+1)/2;}

这个东西鹤起来非常眼熟,因为在<矩形>里用过!

ll calc(ll s, ll w)
{
    if(s < 0 || s-w+1 < 0) return 0;
    return (s+s-w+1)*w/2;
}

当时Chen_jr大佬的原版用的是等差序列求和的形式,然而我并不知道求和公式只是感觉传的参数之间有交叉好麻烦于是就化简了一下,calc(s, w)表示长度为s的大区间内长度为w的子区间个数,这个东西我当时也是用等差序列求和来理解的,然而到了这个题上又忘了这个思路,所以这个题用到这个公式和定长区间统计并没有关系是我跑偏了……

ll calc(ll s, ll w){return s < 0 || w < 0 ? 0 : (s + w) * (s - w + 1) / 2;}

矩形那题%%%Chen_jr用到的式子本来长这样。

于是就结束了,add 存数据方式非常赞。

鹤得很明显
 //原来是等差序列原来是等差序列原来是等差序列原来是等差序列原来是等差序列原来是等差序列
//兴奋死了!!!!!!!!!
//只求和用不着维护序列,这话我好像说过,然而用到的时候就不这么想!!!
//鹤了那就鹤的再彻底一点!
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 1e5 + 5;

int n, m, mx[maxn], st[maxn], top;
ll sval[maxn], ans;
vector<int> mp[maxn];
ll calc(ll x, ll y) {return (x+y)*(y-x+1)/2;}
void ckmx(int &x, int y) {if(x < y) x = y;}

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}

void sol(ll len)
{
    ll now = 0, sum = 0, smax = 0; st[top = 0] = -1;
    for(int i=0; i<m; i++)
    {
        sum += 1ll * sval[i] * (i + 1);
        while(top && mx[st[top]] < mx[i])
        {
            smax -= 1ll * mx[st[top]] * (st[top] - st[top-1]);
            now -= 1ll * mx[st[top]] * calc(i-1-st[top]+1, i-1-st[top-1]);
            top--;
        }
        now += smax;
        smax += 1ll * mx[i] * (i - st[top]);
        now += 1ll * mx[i] * calc(1, i-st[top]);
        st[++top] = i;
        ans += 1ll * len * now - sum;
    }
}

int main()
{
    freopen("building.in", "r", stdin);
    freopen("building.out", "w", stdout);
    
    n = read(), m = read();
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            if(n < m) mp[i-1].push_back(read());
            else mp[j-1].push_back(read());
        }
    }
    if(n > m) swap(n, m);
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++) mx[j] = 0, sval[j] = 0;
        for(int j=i; j<n; j++) 
        {
            for(int k=0; k<m; k++) ckmx(mx[k], mp[j][k]), sval[k] += mp[j][k];
            sol(j - i + 1);
        }
    }
    printf("%lld\n", ans);

    return 0;
}

 

标签:ch,2022NOIPA,33,ll,long,int,maxn,联测,序列
From: https://www.cnblogs.com/Catherine2006/p/16916416.html

相关文章

  • 2022NOIP A层联测33 GCD 简单题 建筑 树上前缀和
    T1:[图论/枚举]给出有边权无向图,边权保证互不相同,Q次询问从S到T的路径中,边权的gcd最大是多少。(n<=1e4,Q<=2e5,w<=1e6)考场根据之前的一道图论题经验,在最短路上加个“\(w......
  • python之路33 MySQL 1
    存取数据的演变1.文本文件文件路径不固定:C:\aaa.txtD:\bbb.txtE:\ccc.txt数据格式不统一:jason|123jason$123jason1232.软件开发目录规范规定......
  • android开发Installed Build Tools revision 33.0.0 is corrupted. Remove and instal
    InstalledBuildToolsrevision33.0.0iscorrupted.RemoveandinstallagainusingtheSDKManager.在你的androidsdk安卓目录中找到buildtools目录中的d8.bat,......
  • 迅为3399开发板Qt蜂鸣器和LED测试
    QLed测试资料在网盘“iTOP-3399开发板\iTOP-3399开发板\02_iTop-RK3399开发资料汇总(不含光盘内容)\05_iTOP-3399开发板Qt应用开发资料\3399开发板QT测试-QtLED......
  • CF433 & 434 题解
    比赛链接:https://codeforces.com/contest/434中国人出的浓度很高的一场kitaharaharuki-北原春希(WA2)KuriyamaMarai-栗山未来(境界的彼方)Ryouko-御门凉子(出包王女......
  • 33. 搜索旋转排序数组
    整数数组 nums 按升序排列,数组中的值 互不相同 。在传递给函数之前,nums 在预先未知的某个下标 k(0<=k<nums.length)上进行了 旋转,使数组变为 [nums[k],nums[k+......
  • CF1733E
    CF1733E给定一个初始箭头全部指向右的网格图,每时刻在\((0,0)\)新增一个黏球,之后黏球按照箭头指示运动一格,并将其刚才所在的上一个格子的箭头变换方向。箭头只会指向右......
  • 洛谷 P3336 [ZJOI2013]话旧
    洛谷P3336[ZJOI2013]话旧图是洛谷搞的做点简单的观察发现,每一次下降必须经过零点。对于每个点,有两种状态,从上面走过来,记为下降;从下面走过来,记为上升。\((0,0)\)我们......
  • CodeForces - 833B The Bakery
    看题解时全程:wow题意:给出n个数,将其按顺序分为k组,令每组的价值为该组不同的数的个数。求一种分法,使得所有组价值和最大。解:设dp[i][j]为将前j个数分为i组时的最大价值......
  • SHELL:echo -e "\033[字背景颜色;字体颜色m字符串\033[0m"
    格式:echo-e"\033[字背景颜色;字体颜色m字符串\033[0m" 例如: echo-e"\033[41;36msomethinghere\033[0m" 其中41的位置代表底色,36的位置是代表字的颜色 那些......