Loading

极长上升子序列部分变形题总结

T1 God Knows

见识的第一道极长上升子序列题目,当时就傻了

因为题目意思的转化的确恶心的一批

更何况还没见过这类问题

首先要知道这道题求的是极长上升子序列的最小权值

使用线段树维护单调栈,线段树里维护三个东西

站底元素,站内最小值,更改后的站内最小值

实际上是使用了一个叫李超线段树的神奇东西

维护的时候一定注意是要先查询右区间,要不会调死。。。、

详情见我的博客

T2 牛半仙的妹子序列

这是今天的比赛题,不过之前的题解鸽太多就还没写到

这个题是找出极长上升子序列的个数

还是李超线段树,线段书维护单调栈

维护的东西有所改变

站底元素,站内序列个数,修改后站内序列个数

跟之前的T1简直一道题在这里粘贴一波板子,以后当作例题使用就行。。。

 1 #include<bits/stdc++.h>
 2 #define lid (id<<1)
 3 #define rid (id<<1|1)
 4 #define int long long
 5 using namespace std;
 6 const int NN=5e6+5,p=998244353;
 7 int n,w[NN],t;
 8 struct SNOWtree{
 9     int ll[NN<<2],rr[NN<<2],down[NN<<2],sum[NN<<2],upsum[NN<<2];
10     void build(int id,int l,int r){
11         ll[id]=l; rr[id]=r; down[id]=-1;
12         if(l==r) return; int mid=l+r>>1;
13         build(lid,l,mid); build(rid,mid+1,r);
14     }
15     int calc(int id,int it){
16         if(ll[id]==rr[id]) return down[id]>it?sum[id]:0;
17         if(down[rid]>it) return (upsum[lid]+calc(rid,it))%p;
18         return calc(lid,it);
19     }
20     void update(int id,int pos,int tail,int v){
21         if(ll[id]==rr[id]){
22             sum[id]=v; down[id]=tail;
23             return;
24         }
25         if(pos<=rr[lid]) update(lid,pos,tail,v);
26         else update(rid,pos,tail,v);
27         down[id]=max(down[lid],down[rid]);
28         sum[id]=(sum[rid]+(upsum[lid]=calc(lid,down[rid])))%p;
29     }
30     int query(int id,int l,int r){
31         if(l<=ll[id]&&rr[id]<=r){
32             int ans=calc(id,t);
33             t=max(down[id],t);
34             return ans;
35         }int ans=0;
36         if(r>=ll[rid]) ans=(ans+query(rid,l,r))%p;
37         if(l<=rr[lid]) ans=(ans+query(lid,l,r))%p;
38         return ans;
39     }
40 }tr;
41 namespace WSN{
42     inline short main(){
43         scanf("%lld",&n);
44         for(int i=1;i<=n;i++) scanf("%lld",&w[i]);
45         n++; w[n]=n; tr.build(1,0,n); tr.update(1,0,0,0);
46          for(int i=1;i<=n;i++){
47             t=-1;
48             int wsn=tr.query(1,0,w[i]-1);
49             if(!wsn) wsn=1;
50             tr.update(1,w[i],i,wsn);
51             if(i==n) printf("%lld\n",wsn);
52         }
53         return 0;
54     }
55 }
56 signed main(){return WSN::main();}
板子

 

posted @ 2021-07-29 17:56  雪域亡魂  阅读(79)  评论(0)    收藏  举报