9.16 小记

唉其实 Zpair 出的模拟赛除了没做上都挺有意思

[POI2011]LIZ-Lollipop

link

题意:给一个只有1和2的序列,每次询问有没有一个子串的和为x

奇妙性质题

性质1:如果 s 可以到达,那么 s-2 必定可以到达

证明:考虑左右两边都是 1 ,就删掉左右两端的数,要不就删掉一个 2

经典说出来觉得很 ** ,但是就是想不到的性质

那么就分奇偶考虑,与全选相同奇偶性且比全选小的一定可以,然后就考虑另外一种情况。

如果删掉一个 2 对奇偶性没有影响,只有删掉 1 才有,所以就是找到离左右端点最近的一,然后只从一端开始删,直到走到那个 1 ,这是另外一种奇偶性能走到的最大值

然后方案就是上面那种方法走一遍就行

[POI2015] WIL

link

嗯我单调队列应该复习一下的

从左向右枚举 r ,可以发现 l 一定单调不降(指选中的区间)。然后就需要一个双指针。对于 \(l\sim r\) 的范围内,你需要维护一个区间内 \(sum[i]-sum[i-d]\) 的最大值,于是你需要一个单调队列。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,d;ll p;
const int maxn=4000020;
ll a[maxn];int q[maxn];
int main()
{
    scanf("%d%d%d",&n,&p,&d);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]),a[i]+=a[i-1];
    int l=1,ans=d;int h=1,t=1;
    q[1]=d;
    for(int i=d+1;i<=n;i++)
    {
        while(h<=t&&a[q[t]]-a[q[t]-d]<a[i]-a[i-d]) t--;
        q[++t]=i;
        while(h<=t&&a[i]-a[l-1]-a[q[h]]+a[q[h]-d]>p)
        {
            l++;
            while(h<=t&&q[h]-d+1<l) h++;
        }
        ans=max(ans,i-l+1);
    }
    printf("%d\n",ans);
}

[HEOI2013]SAO

link

妙妙树形 DP

首先不考虑树的边的方向,那么就是一棵树。树的话,设 DP 状态为 \(f_{i,j}\) 表示第 \(i\) 个节点,当前节点在 \(i\) 的子树内排名第 \(j\) 的方案数。

然后考虑怎么将新来的一棵子树 \(v\) 加入到他的父亲上。

首先是考虑 \(a[p]<a[v]\) 的情况,我们现在要转移到 \(f_{p,k}\) ,我们要枚举 \(j\) 表示在插入新子树前的 \(p\) 的排名,再枚举 \(l\) 表示 \(v\) 在它自己的子树上的排名。因为在 \(p\) 前面要填满 \(k\) 个,而它前面已经有 \(j\) 个了,所以 \(l \geq k-j\)

首先考虑 \(p,v\) 前面的情况,就是最后在 \(p\) 前有 \(k-1\) 个数,而一开始有 \(j-1\) 个,所以前面的方案数的贡献为 \(C_{k-1}^{j-1}\) ,然后考虑在后面的情况,就是在 \(p\) 后面有 \(siz[p]+siz[v]-k\) 个数,然后一开始有 \(siz[p]-j\) 个,所以这部分贡献的答案为 \(C_{siz[p]+siz[v]-k}^{siz[p]-j}\)

然后写出来就是 \(\displaystyle f_{p,k}=\sum_{j=1}^{siz[p]}\sum_{l=k-j}^{siz[v]} f_{p,j}f_{v,l}C_{siz[p]+siz[v]-k}^{siz[p]-j}C_{k-1}^{j-1}\)

\(a[p]>a[v]\) 的情况同理。

这个复杂度是 \(n^3\) 的吧

然后那一坨式子带 \(p\) 的都提出来,剩下的就前缀和优化一下。变成 \(O(n^2)\)

[COCI2021-2022#2] Osumnjičeni

link

对于要查询的 \(l,r\) ,对于 \(l\) 贪心地一定要去找尽可能长的右端点去跳。

那么就要先求出对于每一个 \(l\), 那个最远的区间能到哪里。我们用单调队列加线段树维护。当加入一个区间时,在权值线段树上查询有无交叉的区间。如果有就弹出队首并记录下队首的最远距离。

然后是个优秀的套路

给你一堆区间,问需要最少多少区间能够将一段给定区间覆盖。我们使用倍增,\(f[i][j]\) 表示 \(i\) 为起点,跳 \(2^j\) 步能跳到的区间头。

然后倍增地找就行了

然后这个性质的话应该是这个题 CF1175E

#include <bits/stdc++.h>
using namespace std;
const int maxn=4000200;
int n,lx[maxn],rx[maxn];
int c[maxn*8],lzy[maxn];
#define lson(p) ((p)<<1)
#define rson(p) ((p)<<1|1)
void pushdown(int p,int l,int r)
{
    int mid=(l+r)>>1;
    c[lson(p)]+=(mid-l+1)*lzy[p]; c[rson(p)]+=(r-mid)*lzy[p];
    lzy[lson(p)]+=lzy[p];lzy[rson(p)]+=lzy[p];
    lzy[p]=0;
}
void update(int l,int r,int x,int y,int v,int p)
{
    if(x<=l&&y>=r)
    {
        c[p]+=(r-l+1)*v; lzy[p]+=v;return;
    }
    int mid=(l+r)>>1;
    if(x<=mid) update(l,mid,x,y,v,lson(p));
    if(y>mid) update(mid+1,r,x,y,v,rson(p));
    c[p]=(c[lson(p)]+c[rson(p)]);
}
int query(int l,int r,int x,int y,int p)
{
    if(x<=l&&y>=r) return c[p];
    int mid=(l+r)>>1,ret=0;
    if(lzy[p]) pushdown(p,l,r);
    if(x<=mid) ret+=query(l,mid,x,y,lson(p));
    if(y>mid) ret+=query(mid+1,r,x,y,rson(p));
    return ret;
}
int f[maxn][21];int a[maxn],cnt,q[maxn];
int main()
{
   // freopen("p.in","r",stdin);
    //freopen("p.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&lx[i],&rx[i]);
        a[++cnt]=lx[i];a[++cnt]=rx[i];
    }
    sort(a+1,a+1+cnt);int ccnt=unique(a+1,a+1+cnt)-a;
    for(int i=1;i<=n;i++)
    {
        lx[i]=lower_bound(a+1,a+1+ccnt,lx[i])-a;
        rx[i]=lower_bound(a+1,a+1+ccnt,rx[i])-a;
    }
    int l=1,r=0;
    for(int i=1;i<=n;i++)
    {
        while(r>=1&&query(1,2*n,lx[i],rx[i],1))
        {
            f[l][0]=i;update(1,2*n,lx[q[l]],rx[q[l]],-1,1);
            l++;
        }
        q[++r]=i;
        update(1,2*n,lx[i],rx[i],1,1);
    }
    for(int i=l;i<=r;i++) f[q[i]][0]=n+1;
    f[n+1][0]=n+1;
    for(int i=n+1;i>=1;i--)
    {
        for(int j=1;j<=20;j++) f[i][j]=f[f[i][j-1]][j-1];
    }
    int Q;scanf("%d",&Q);
    while(Q--)
    {
        int p,q;scanf("%d%d",&p,&q);
        int ans=1;
        for(int i=20;i>=0;i--)
        {
            if(f[p][i]<=q) p=f[p][i],ans+=(1<<i);
        }
        printf("%d\n",ans);   
    }
}

废话

嘛,没啥,嗯,就是,没啥要说的。早点休息,没什么要顾虑的就是了

自由的夏虫编织着美梦解渴

单薄的外壳 展开花纹

尽将内心诉说

鞘翅振涌

卷起击碎定论的漩涡

等待 数百天伏蛰

这一瞬冲破

最高亢的歌 予我

肆意鸣唱

直到 嘶哑那刻

posted @ 2022-09-25 17:57  cc0000  阅读(19)  评论(0编辑  收藏  举报