首页 > 其他分享 >CF1621G Weighted Increasing Subsequences 题解

CF1621G Weighted Increasing Subsequences 题解

时间:2024-09-09 20:37:45浏览次数:1  
标签:cnt Weighted int 题解 void disc lis Increasing mx

题目链接

点击打开链接

题目解法

这种题就感觉每一步都不难想,但串在一起就不会

显然考虑位置 \(x\) 作为 \(lis\) 的一部分,合法的 \(lis\) 的个数
合法的约束是:令 \(lis\) 的最后一个位置为 \(last\),满足 \(\max\{a_{last+1},...,a_n\}>a_x\)
不难发现,合法的 \(last\) 是一段区间 \([x,r_x]\),且 \(r_x\) 不难求出
容斥一下,相当于 经过点 \(x\) 的 \(lis\) 个数 \(-\) 经过点 \(x\) 且 \(last\) 在 \((r_x,n]\) 的 \(lis\) 个数
前一部分是好求的
后一部分我们考虑 \(r_i\) 实际上是最后一个满足 \(a_{r_x+1}>a_x\) 的位置,所以 \((r_x+1,n]\) 的位置一定不能作为 \(last\),这等价于我们需要求 经过 \(x\),且在 \(r_x+1\) 结束的 \(lis\) 个数
我们考虑 \(r_x\) 一定是最远能结束的 \(lis\) 的位置,所以在树状数组中多记一维就好了

时间复杂度 \(O(\sum n\log n)\)

#include <bits/stdc++.h>
#define F(i,x,y) for(int i=(x);i<=(y);i++)
#define DF(i,x,y) for(int i=(x);i>=(y);i--)
#define ms(x,y) memset(x,y,sizeof(x))
#define SZ(x) (int)x.size()-1
#define all(x) x.begin(),x.end()
#define pb push_back
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T> void chkmax(T &x,T y){ x=max(x,y);}
template<typename T> void chkmin(T &x,T y){ x=min(x,y);}
template<typename T> void read(T &FF){
    FF=0;int RR=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
    for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
    FF*=RR;
}
const int N=200010,P=1e9+7;
int n,cnt,a[N],disc[N],mx[N],nxt[N];
int pre[N],suf[N],f[N];
inline void inc(int &x,int y){ x+=y;if(x>=P) x-=P;}
inline void dec(int &x,int y){ x-=y;if(x<0) x+=P;}
#define lowbit(x) x&-x
struct fenwick{
    int tr[N];
    void add(int x,int v){ for(;x<=cnt;x+=lowbit(x)) inc(tr[x],v);}
    int ask(int x){ int res=0;for(;x;x-=lowbit(x)) inc(res,tr[x]);return res;}
    void clr(){ F(i,1,n) tr[i]=0;}
}fwk;
struct fenwick2{
    int tr[N],mx[N];
    void add(int x,int to,int v){
        for(;x<=cnt;x+=lowbit(x)){
            if(to>mx[x]) mx[x]=to,tr[x]=0;
            if(to==mx[x]) inc(tr[x],v);
        }
    }
    pii ask(int x){
        int to=0,res=0;
        for(;x;x-=lowbit(x)){
            if(mx[x]>to) to=mx[x],res=0;
            if(mx[x]==to) inc(res,tr[x]);
        }
        return {to,res};
    }
    void clr(){ F(i,1,n) tr[i]=mx[i]=0;}
}fwk2;
void work(){
    read(n);
    F(i,1,n) read(a[i]),disc[i]=a[i];
    sort(disc+1,disc+n+1);
    cnt=unique(disc+1,disc+n+1)-disc-1;
    F(i,1,n) a[i]=lower_bound(disc+1,disc+cnt+1,a[i])-disc;
    mx[n+1]=0;
    DF(i,n,1) mx[i]=max(mx[i+1],a[i]);
    F(i,1,n){
        int lo=i,hi=n+1;
        while(lo<hi-1){
            int mid=(lo+hi)>>1;
            if(mx[mid]>a[i]) lo=mid;
            else hi=mid;
        }
        nxt[i]=lo;
    }
    fwk.clr();
    F(i,1,n) pre[i]=(fwk.ask(a[i]-1)+1)%P,fwk.add(a[i],pre[i]);
    fwk.clr();
    DF(i,n,1) suf[i]=(fwk.ask(cnt-a[i])+1)%P,fwk.add(cnt-a[i]+1,suf[i]);
    int ans=0;
    F(i,1,n) inc(ans,1ll*pre[i]*suf[i]%P);
    fwk2.clr();
    DF(i,n,1){
        auto [to,v]=fwk2.ask(cnt-a[i]);
        if(a[i]==mx[i]) to=i,v=1;
        fwk2.add(cnt-a[i]+1,to,v);
        dec(ans,1ll*pre[i]*v%P);
    }
    printf("%d\n",ans);
}
int main(){
    int T;read(T);
    while(T--) work();    
    return 0;
}

标签:cnt,Weighted,int,题解,void,disc,lis,Increasing,mx
From: https://www.cnblogs.com/Farmer-djx/p/18405281

相关文章

  • 【最新华为OD机试E卷-支持在线评测】通过软盘拷贝文件(200分)多语言题解-(Python/C/Ja
    ......
  • P7230 题解
    P7230思路对每个左端点维护右端点\(res_i\)。操作形如删去一个数再加入一个数。如果删掉\(p\)上的\(a_p\),找到左右最近的\(l,r\)使得\(a_l=a_r=a_p\)。那么\(res_{l+1},\dotsb,res_p\)对\(r\)取max。实际上要维护\(\maxres_i-i+1\),因为\(res_i\)单调,所以相当于......
  • 【题解】Solution Set - NOIP2024集训Day25 概率期望 dp
    【题解】SolutionSet-NOIP2024集训Day25概率期望dphttps://www.becoder.com.cn/contest/5515「QOJ2606」Gachapon\(f_{i,j}\):用一次合法的level-irolling能够抽到的\(j\)的期望个数。\(h_{i,j,k}\):在\(i\)次操作之内,抽到恰好\(k\)个\(j\)的概率。\[h_{i,j,k......
  • luogu4198题解
    随机说话这个题做法没见过记一下。我一开始以为是李超树的题,结果把李超树打上之后就不会做了。然后题读错了写了一个弱化版。题目分析做法参考这个题题意只是假装是一个有关线段的题。简化之后的题意如下。有一个初始都为\(0\)的实数数列,每一次会修改位置\(x\)的数为......
  • Flutter 3.24 构建 release 抛出部分依赖 AAPT: error: resource android:attr/lStar
    问题截图:一些讨论:https://github.com/transistorsoft/flutter_background_fetch/issues/369问题原因及解决方案:@Aziz-T该问题与插件的compileSdkVersion和targetSdkVersion有关。出现该问题的原因是部分插件的compileSdkVersion和targetSdkVersion版本过旧。请前往......
  • P2471 [SCOI2007] 降雨量 题解
    题目传送门分析分讨题。首先发现是RMQ问题(区间最值),可以用线段树或ST表来维护(代码为线段树,因为我忘记ST表怎么写了)。然后发现有些年份不明确导致区间判断似乎不好搞。但事实上只要判断下标差是否等于年份差即可得出该区间有无不明确年份。其次考虑“必真”,“必假”,“......
  • 【洛谷 P1996】约瑟夫问题 题解(数组+模拟+循环)
    约瑟夫问题题目描述个人围成一圈,从第一个人开始报数,数到的人出列,再由下一个人重新从开始报数,数到的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰名小朋友,而该题是全部出圈。输入......
  • 题解 GZOI2023D2B【乒乓球】
    4s,512M题目描述Alice和Bob在打乒乓球,乒乓球比赛的规则是这样的:一场比赛中两位选手将进行若干局比赛,选手只需要赢得\(X\)局比赛就宣告其胜利;每局比赛中两位选手将进行若干盘比赛,选手只需要赢得\(Y\)盘比赛就宣告其胜利;每盘比赛中两位选手将进行乒乓球对决,有且仅有一位选......
  • AtCoder Beginner Contest 274 A~E 题解
    吐槽:这比赛名字为啥没有英文版。。。A-BattingAverage题目大意给定整数\(A,B\),输出\(\fracBA\),保留三位小数。\(1\leA\le10\)\(0\leB\leA\)分析签到题,使用printf或cout格式化输出即可。代码#include<cstdio>usingnamespacestd;intmain(){ inta,b; sc......
  • TOYOTA MOTOR CORPORATION Programming Contest 2023#1 (AtCoder Beginner Contest 29
    好久没写题解了,这就来水一篇。A-JobInterview题目大意给定一个长为\(N\)的字符串\(S\),由o、-、x组成。判断\(S\)是否符合下列条件:\(S\)中至少有一个o。\(S\)中没有x。\(1\leN\le100\)分析签到题。直接按题意模拟即可。代码#include<cstdio>usingn......