首页 > 其他分享 >9.16 小记

9.16 小记

时间:2022-09-25 18:13:29浏览次数:84  
标签:lzy 9.16 siz rson mid int maxn 小记

唉其实 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);   
    }
}

废话

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

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

单薄的外壳 展开花纹

尽将内心诉说

鞘翅振涌

卷起击碎定论的漩涡

等待 数百天伏蛰

这一瞬冲破

最高亢的歌 予我

肆意鸣唱

直到 嘶哑那刻

标签:lzy,9.16,siz,rson,mid,int,maxn,小记
From: https://www.cnblogs.com/cc0000/p/16728390.html

相关文章

  • 数分技巧小记
    设\(\mathbb{F},A\)为两个集合,\(\forallx\in\mathbbF,\operatorname{card}(f(x))=\operatorname{card}(A)\),那么有\(\operatorname{card}(\mathbbF\timesA......
  • 立创EDA添加仿真模型小记
    绘制仿真符号类同原理图,略添加器件仿真模型仿真模型代码简介Proteus的SPICE模型[https://www.cnblogs.com/lsgxeva/p/14141237.html]Proteus主要使用使用符合SPICE......
  • 9.23 小记
    9.23模拟赛没啥好说的就枚举子集警钟敲烂:for(intj=i;j;j=(j-1)&i)没了,题答和骗分过样例谁乐意写谁写反正我不写[Code+#3]寻找车位线段树+单调队列首先是暴力的话......
  • 2022.9.16———HZOI【CSP-S开小灶5】游寄
    \(Preface\)\(Rank46/41\)\(15pts+30pts=45pts\)\(\mathfrak{T1}\乌鸦喝水\)这个题的题意太坑人了,说的根本不清楚,样例也水,导致我挂成这弔样他的意思是,乌鸦一共飞......
  • 9.16-17四则运算2
     packagetemomomomo;importjava.util.Random;importjava.util.Scanner;publicclasssizeyunsuan2{  staticScannerin=newScanner(System.in);//一定要......
  • 9.16课堂测试
    于9.17完成。importjava.util.Scanner;importjava.util.ArrayList;importjava.util.Random;importjava.math.BigInteger;publicclassCalculates{  stat......
  • 2022.09.16 模拟赛小结(互测)
    2022.09.16模拟赛小结(互测)目录2022.09.16模拟赛小结(互测)题面更好的阅读体验戳此进入赛时思路T1CodeT2CodeT3CodeT4Code正解T1UPD题面PDF链接(这个链接只是为了自己方......
  • 2022.9.16课后博客
    static关键字在类中,用static声明的成员变量为静态成员变量,也成为类变量。类变量的生命周期和类相同,在整个应用程序执行期间都有效。这里要强调一下:static修饰的成员变量......
  • 【三分小记】
    众所周知,三分可以求单峰函数极值那么首先要明确单峰函数的定义:它们有唯一的极大值点,在极大值左侧严格单调上升,右侧严格单调下降(单谷函数相反)注意单峰函数并不一定是凸函......
  • 8.26~9.3小记
    记录一下这几天场切的一些我觉得比较难的题,以及一些练习题。题目名算法感悟P5050【模板】多项式多点求值多项式取模,分治FFT现在才学多少有点逊P5606小K......