noip模拟赛

190滚粗QAQ

T1

「LibreOJ NOI Round #1」接竹竿

一天,神犇和 LCR 在玩扑克牌。他们玩的是一种叫做“接竹竿”的游戏。

游戏规则是:一共有 nnn 张牌,每张牌上有一个花色 ccc 和一个点数 vvv,花色不超过 kkk 种。将这些牌依次放入一列牌的末端。若放入之前这列牌中已有与这张牌花色相同的牌,你可以选择将这张牌和任意一张花色相同的牌之间的所有牌全部取出队列(包括这两张牌本身),并得到与取出的所有牌点数和相同的分数。现在已知 LCR 把这 nnn 张牌放入队列的顺序,求她最多能得多少分。

输入顺序即为 LCR 放入队列的顺序。即,cic_ici​​ 表示第 iii 张放入的牌的花色,viv_ivi​​ 表示第 iii 张放入的牌的点数。

请注意,如果你知道类似的纸牌游戏,请尤其仔细地阅读规则,以免因为理解题意错误而出现不必要的问题。

sol:sb题

首先我们得到一个dp

$$f_i = max{f_{j-1} - sumv_{j - 1} + sumv_i}(c_i = c_j)$$

$sumv_x$表示$sum^{x}_{i=1}v_i$

然后发现$f_{j-1} - sumv_{j - 1}$只与$j - 1$有关,剩下的只与$i$有关

于是记一个$lst[j]$表示颜色$j$的$f_{j-1} - sumv_{j - 1}$就可以了

转移的时候可以一起转移,然后就$O(n)$了

T2 scoi2007降雨量

题面不用说了吧...本地AC提交RE

然后我还真RE了QAQ

后来发现是下面写的时候年份和降雨量全写反了QAQ

QAQ

T3 焚风现象

IOI 王国永远刮着海风。风从地点 000 依次吹到地点 111,地点 222 ……直到地点 NNN,共 N+1N+1N+1 个地点。JOI 君住在地点 NNN。地点 000 的海拔 A0=0A_0=0A0​​=0,地点 i(1⩽i⩽N)i(1leqslant ileqslant N)i(1iN) 的海拔为 AiA_iAi​​。
地表风的温度随海拔升降而变化。地点 000 在海边,温度为 000 度;对于任一地点 i(0⩽i<N) i(0leqslant i<N)i(0i<N),从地点 iii 吹到地点 i+1i+1i+1 的风的温差仅取决于两地的海拔差。具体来说:

  • 如果 Ai=Ai+1A_i=A_{i+1}Ai​​=Ai+1​​,风的温度不变;
  • 如果 Ai<Ai+1A_i<A_{i+1}Ai​​<Ai+1​​,风每爬升 111 米,温度就会下降 SSS 度;
  • 如果 Ai>Ai+1A_i> A_{i+1}Ai​​>Ai+1​​,风每下沉 111 米,温度就会升高 TTT 度。

IOI 国的地壳运动很强烈。你得到了 QQQ 天来地壳运动的数据。在第 jjj 日 (1⩽j⩽Q)(1leqslant jleqslant Q)(1jQ),地点 Lj,Lj+1,…,Rj(1⩽Lj⩽Rj⩽N)L_j, L_j+1, ldots, R_j (1leqslant L_jleqslant R_jleqslant N)Lj​​,Lj​​+1,,Rj​​(1Lj​​Rj​​N) 的海拔升高了 XjX_jXj​​,注意 XjX_jXj​​ 可能是负数。
你的任务是,计算每天地壳运动后 JOI 君住所的温度。

sol:发现这题海拔这个东西是没用的,只有相对海拔是有用的。。。

我们可以维护一个差分数组,每次修改相当于区间加,然后单点查询更新答案就可以了

这样我们可以线段树

但考虑差分的性质,我们可以并不用区间加

只要考虑左右两个端点就可以了

一次修改相当于在$l$处加一次,在$r + 1$处减一次

然后就可以$O(n)$

//wls niubi!
#include<bits/stdc++.h>
#define LL long long
using namespace std;
inline int read()
{
    int x = 0,f = 1;char ch = getchar();
    for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
    for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';
    return x * f;
}
const int maxn = 1e6 + 10;
int n,k;
int c[maxn],v[maxn];
LL s[maxn],dp[maxn],mem[maxn];
int main() 
{
    n = read(),k = read();
    memset(mem,128,sizeof(mem));
    for(int i=1;i<=n;i++)c[i] = read();
    for(int i=1;i<=n;i++)v[i] = read();
    for(int i=1;i<=n;i++)s[i] = s[i - 1] + v[i];
    for(int i=1;i<=n;i++)
    {
        dp[i] = max(dp[i - 1],mem[c[i]] + s[i]);
        mem[c[i]] = max(mem[c[i]],dp[i - 1] - s[i - 1]);
    }
    printf("%lld
",dp[n]);
}
T1
//wls niubi!
#include<bits/stdc++.h>
#define LL long long
using namespace std;
inline int read()
{
    int x = 0,f = 1;char ch = getchar();
    for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
    for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';
    return x * f;
}
const int maxn =  100010;
int y[maxn],a[maxn];
int n,m;
namespace RMQ
{
    int lg[maxn];int st[20][maxn];
    inline void init()
    {
        lg[0] = -1;
        for(int i=1;i<=n;i++)lg[i] = lg[i >> 1] + 1,st[0][i] = a[i];
        int logn = lg[n];
        for (int i=1;i<=logn;i++)
            for (int j=1;j<=n-(1 << i)+1;j++)
                st[i][j] = max(st[i - 1][j],st[i - 1][j + (1 << i - 1)]);
    }
    inline int query(int L,int R)
    {
        if(L > R)return -2147483233; 
        int dep = lg[R - L + 1];
        return max(st[dep][L],st[dep][R - (1 << dep) + 1]);
    }
}
using namespace RMQ;
inline int getpos(int x){return (lower_bound(y + 1,y + n + 1,x) - y);}
int main()
{
    n = read();
    for(int i=1;i<=n;i++)y[i] = read(),a[i] = read();
    m = read();
    init();
    while(m--)
    {
        int ret;
        int x = read(),yy = read();
        int l = getpos(x),r = getpos(yy);
        //if(l == r)TRUE()
        int l_exist = (l <= n && y[l] == x),r_exist = (r <= n && y[r] == yy);
        if(!r_exist)--r;
        if(l_exist)
        {
            if(r_exist)
            {
                int num = query(l + 1,r - 1);
                if(a[l] < a[r])ret = 0;
                else
                {
                    if(num < a[r])
                    {
                        if(r - l == yy - x)ret = 1;
                        else ret = -1;
                    }
                    else ret = 0;
                }
            }
            else
            {
                int num = query(l + 1,r);
                if(num < a[l])ret = -1;
                else ret = 0;
            }
        }
        else
        {
            if(r_exist)
            {
                int num = query(l,r - 1);
                if(num < a[r])ret = -1;
                else ret = 0;
            }
            else ret = -1;
        }
        if(ret == 0)puts("false");
        else if(ret == 1)puts("true");
        else puts("maybe");
    }
}
T2
//wls niubi!
#include<bits/stdc++.h>
#define LL long long
using namespace std;
inline int read()
{
    int x = 0,f = 1;char ch = getchar();
    for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
    for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';
    return x * f;
}
const int maxn = 2000010;
int n,q,s,t;
LL sum;
inline LL jisuan(LL x)
{
    if(x < 0)return t * -x;
    else return s * -x;
}
LL a[maxn],delt[maxn];
int main()
{
//    freopen("gen.in","r",stdin);
//    freopen("zj.out","w",stdout);
    n = read(),q = read(),s = read(),t = read();
    for(int i=0;i<=n;i++)a[i] = read();
    for(int i=1;i<=n;i++)
    {
        delt[i] = a[i] - a[i - 1];
        sum += jisuan(delt[i]);
    }
    while(q--)
    {
        int l = read(),r = read(),val = read();
        if(l != 0)
        {
            sum -= jisuan(delt[l]);
            delt[l] += val;
            sum += jisuan(delt[l]);
        }
        if(r != n)
        {
            sum -= jisuan(delt[r + 1]);
            delt[r + 1] -= val;
            sum += jisuan(delt[r + 1]);
        }
        printf("%lld
",sum);
    }
}
T3

T3还写挂了一次

190滚粗

%%%wls

原文地址:https://www.cnblogs.com/Kong-Ruo/p/9670785.html