牛半仙的妹子序列

牛半仙的妹子序列

https://ac.nowcoder.com/acm/contest/7615/D

牛半仙的妹子序列

题解:

考虑

对于第个点,考虑哪些点对是有贡献的。记点到点间比大的最小值为,那么只要那么这个点就会有贡献。所以我们要维护这个

怎么维护呢,对于一个新加入的值,那些值小于的点的就要和

维护这个,只观察,发现每次操作可以看成比大的数变成,每次操作都会少一段值相同的区间。总共只有段区间,所以最多操作次,时间复杂度:

用线段树处理应该复杂度一样的吧(作者太菜不会证)。

代码:

#include<bits/stdc++.h>
using namespace std;
#define next Next
#define gc getchar
#define int long long
const int mod=998244353;
const int N=1e6+5;
int n,m,ans,a[N],f[N];
struct node{
    int val,gs;
}tree[N*4];
node operator + (node a,node b)
{
    if(a.val>b.val)return a;
    if(a.val<b.val)return b;
    return (node){a.val,(a.gs+b.gs)%mod};
}
//char buf[1<<21],*p1=buf,*p2=buf;
//inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
inline int read()
{
    int ret=0,f=0;char c=gc();
    while(!isdigit(c)){if(c=='-')f=1;c=gc();}
    while(isdigit(c)){ret=ret*10+c-48;c=gc();}
    if(f)return -ret;return ret;
}
void change(int nod,int l,int r,int L,int R,int x)
{
    if(l>=L&&r<=R&&tree[nod].val<x)return;
    if(l>R||r<L)return;
    if(l==r)
    {
        tree[nod].val=x;
        return;
    }
    int mid=(l+r)/2;
    change(nod*2,l,mid,L,R,x);
    change(nod*2+1,mid+1,r,L,R,x);
    tree[nod]=tree[nod*2]+tree[nod*2+1];
}
node find(int nod,int l,int r,int L,int R)
{
    if(l==L&&r==R)return tree[nod];
    int mid=(l+r)/2;
    if(R<=mid)return find(nod*2,l,mid,L,R);
    else if(L>mid)return find(nod*2+1,mid+1,r,L,R);
    else return find(nod*2,l,mid,L,mid)+find(nod*2+1,mid+1,r,mid+1,R);
}
void change2(int nod,int l,int r,int x,int val)
{
    if(l==r)
    {
        tree[nod].val=n+1;
        tree[nod].gs=val;
        return;
    }
    int mid=(l+r)/2;
    if(x<=mid)change2(nod*2,l,mid,x,val);
    else change2(nod*2+1,mid+1,r,x,val);
    tree[nod]=tree[nod*2]+tree[nod*2+1];
}
signed main()
{
    n=read();
    for(int i=1;i<=n;i++)a[i]=read();
    for(int i=1;i<=n;i++)
    {
        change(1,1,n,1,a[i],a[i]);
        node x=find(1,1,n,1,a[i]);
        if(x.val==a[i])f[i]=x.gs;
        else f[i]=1;
        change2(1,1,n,a[i],f[i]);
    }
    cout<<tree[1].gs;
    return 0;
}
xuxuxuxuxu 文章被收录于专栏

信息学竞赛

全部评论
您的代码好像无法通过数据200000\n 100000,99999,99998...2,1, 200000,199999...100002,100001,如果按照您的线段树取min方式,后半段每一个数a[i]>100000都需要更新线段树上[1,100000]所有节点的min值
1 回复 分享
发布于 2020-11-08 21:52
这复杂度是 O(n^2logn) 的吧?
点赞 回复 分享
发布于 2020-11-24 11:46

相关推荐

10-19 10:28
已编辑
成都理工大学 后端工程师
团孝子已上线feeling:面了很多家公司,能感受到目前只有小公司+外包喜欢问八股。大厂虽然也问八股,但是是从实习、项目中进行提问,并且大厂会问很深,面试官也会对你的回答进行思考➕追问,所以准备大厂面试前一定要备好相关资料。对于算法,我做的是codetop前100+力扣hot100+力扣高频150,面试中实感hot100就足够,基本上只要是hot100就秒答。对于项目和八股,我做的也是烂大街的星球项目,八股则是看小林和问ai,自己也写了很多技术博客和画了很多思维导图,并且自己也尝试用嘴巴说出来,不只停留于纸面。运气也很重要,必须要让面试官/HR看到简历才行,所以建议投递时间是下午两点。tl:第一岗位9.9&nbsp;投递9.10&nbsp;一面(一面评价:最近见过最强的大三,结束五分钟后约二面,都晚上九点了不下班吗)9.11&nbsp;二面(三道算法a出两道,反问评价:经验不够等横向,我实习生要啥经验)9.21挂(实习时间过短+其他原因,想要一年实习的,为什么不招个正职)第二岗位10.10投递10.11约面(主管打电话,说看到我之前投递记录了想要我挂qa职进去干后端,同意)10.14&nbsp;一面(无八股,主动说确实很强,意愿很强)10.16&nbsp;oc其余,友邦,东软,东华,惠择,用友oc已拒京东测开一面挂(投后端被测开捞)腾讯测试已拒(投后端被测开捞)ps:表扬惠择的主管面,没怎么问技术(可能是一面面试官沟通过了),全程一起讲大道理,解答了心中很多疑惑,也告诉我以面试官角度来看怎么选候选人,如果可以下次一定选惠择
越今朝0:慧择一共几面啊,我二面后就没声音了。。
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务