题面

传送门

题解

我的做法似乎非常复杂啊……

首先最长上升子序列长度就等于把它反过来再接到前面求一遍,比方说把\(2134\)变成\(43122134\),实际上变化之后的求一个最长上升子序列和方案数就是答案了

最长上升子序列随便求求,主要是这个方案数很麻烦啊……我的做法是对每一个长度开一个动态开点线段树,然后每次在对应的长度里二分跑前缀和

其实这里完全不用动态开点线段树的,直接把权值离散一下然后一棵线段树就够了,跑得飞快

其实这里连线段树都不需要直接树状数组就可以维护前缀最大值和方案之和了

然后没有然后了

//minamoto
#include<bits/stdc++.h>
#define R register
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(int i=(a),I=(b)-1;i>I;--i)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=4e5+5,P=1e9+7,M=(N<<5)+5;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
return res;
}
int sum[M],lc[M],rc[M],rt[N],tot;
int a[N],f[N],g[N],b[N],m,n,res,mx,lim;
void query(int p,int l,int r,int x){
if(!p||l==r)return res=add(res,sum[p]),void();
int mid=(l+r)>>1;
if(x<=mid)query(lc[p],l,mid,x);
else res=add(res,sum[lc[p]]),query(rc[p],mid+1,r,x);
}
void ins(int &p,int l,int r,int x,int val){
if(!p)p=++tot;sum[p]=add(sum[p],val);
if(l==r)return;
int mid=(l+r)>>1;
x<=mid?ins(lc[p],l,mid,x,val):ins(rc[p],mid+1,r,x,val);
}
int main(){
// freopen("testdata.in","r",stdin);
n=read();
fp(i,1,n)a[i]=b[i]=read();
sort(b+1,b+1+n),lim=unique(b+1,b+1+n)-b-1;
fp(i,1,n)a[i]=lower_bound(b+1,b+1+lim,a[i])-b;
reverse(a+1,a+1+n);
fp(i,1,n)a[(n<<1)-i+1]=a[i];
n=(n<<1),m=0,b[0]=0;
fp(i,1,n){
if(a[i]>b[m])f[i]=++m,b[m]=a[i];
else{
int k=lower_bound(b+1,b+1+m,a[i])-b;
f[i]=k,b[k]=a[i];
}
if(f[i]==1)g[i]=1;
else res=0,query(rt[f[i]-1],1,lim,a[i]-1),g[i]=res;
if(i>(n>>1)&&f[i]==f[n-i+1])g[i]=dec(g[i],g[n-i+1]);
ins(rt[f[i]],1,lim,a[i],g[i]);
cmax(mx,f[i]);
}
res=0;
fp(i,(n>>1)+1,n)if(f[i]==mx){
res=add(res,g[i]);
if(f[n-i+1]==mx)res=add(res,g[n-i+1]);
}
res=mul(res,ksm(2,(n>>1)-mx));
printf("%d %d\n",mx,res);
return 0;
}

LOJ#6048. 「雅礼集训 2017 Day10」数列(线段树)的更多相关文章

  1. loj#6029. 「雅礼集训 2017 Day1」市场(线段树)

    题意 链接 Sol 势能分析. 除法是不能打标记的,所以只能暴力递归.这里我们加一个剪枝:如果区间内最大最小值的改变量都相同的话,就变成区间减. 这样复杂度是\((n + mlogn) logV\)的 ...

  2. loj #6032. 「雅礼集训 2017 Day2」水箱 线段树优化DP转移

    $ \color{#0066ff}{ 题目描述 }$ 给出一个长度为 \(n\) 宽度为 \(1\) ,高度无限的水箱,有 \(n-1\) 个挡板将其分为 \(n\) 个 \(1 - 1\) 的小格, ...

  3. LOJ #6029. 「雅礼集训 2017 Day1」市场 线段树维护区间除法

    题目描述 从前有一个贸易市场,在一位执政官到来之前都是非常繁荣的,自从他来了之后,发布了一系列奇怪的政令,导致贸易市场的衰落. 有 \(n\) 个商贩,从\(0 \sim n - 1\) 编号,每个商 ...

  4. LOJ#6049. 「雅礼集训 2017 Day10」拍苍蝇(计算几何+bitset)

    题面 传送门 题解 首先可以用一个矩形去套这个多边形,那么我们只要枚举这个矩形的左下角就可以枚举完所有多边形的位置了 我们先对每一个\(x\)坐标开一个\(bitset\),表示这个\(x\)坐标里哪 ...

  5. LOJ#6047. 「雅礼集训 2017 Day10」决斗(set)

    题面 传送门 题解 这么简单一道题我考试的时候居然只打了\(40\)分暴力? 如果我们把每个点的\(a_i\)记为\(deg_i-1\),其中\(deg_i\)表示有\(deg_i\)个数的\(A_i ...

  6. 【loj6029】「雅礼集训 2017 Day1」市场 线段树+均摊分析

    题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有四种:区间加.区间下取整除.区间求最小值.区间求和. $n\le 100000$ ,每次加的数在 $[-10^4,10^4]$ 之 ...

  7. 「雅礼集训 2017 Day1」市场 (线段树除法,区间最小,区间查询)

    老师说,你们暴力求除法也整不了多少次就归一了,暴力就好了(应该只有log(n)次) 于是暴力啊暴力,结果我归天了. 好吧,在各种题解的摧残下,我终于出了一篇巨好看(chou lou)代码(很多结构体党 ...

  8. #6029. 「雅礼集训 2017 Day1」市场 [线段树]

    考虑到每次除法,然后加法,差距会变小,于是维护加法lazytag即可 #include <cstdio> #include <cmath> #define int long l ...

  9. [LOJ 6031]「雅礼集训 2017 Day1」字符串

    [LOJ 6031] 「雅礼集训 2017 Day1」字符串 题意 给定一个长度为 \(n\) 的字符串 \(s\), \(m\) 对 \((l_i,r_i)\), 回答 \(q\) 个询问. 每个询 ...

随机推荐

  1. 数据挖掘比赛----Kaggle实战

    http://www.cnblogs.com/kobedeshow/p/4118361.html

  2. XGBoost参数调优

    XGBoost参数调优 http://blog.csdn.net/hhy518518/article/details/54988024 摘要: 转载:http://blog.csdn.NET/han_ ...

  3. Application.streamingAssetsPath

    [Application.streamingAssetsPath] This API contains the path to the StreamingAssets folder (Read Onl ...

  4. go_goroutine and channel

    协程Coroutine 轻量级”线程“ 非抢占式多任务处理,由协程主动交出控制权(如果程序中间没有print,程序会一直霸占着调度器) 编译器/解释器/虚拟机层面的多任务 多个协程可能在一个或多个线程 ...

  5. 286 walls and gate最近的出口

    [抄题]: 您将获得一个使用这三个可能值初始化的 m×n 2D 网格.-1 - 墙壁或障碍物. 0 - 门. INF - Infinity是一个空房间.我们使用值 2 ^ 31 - 1 = 21474 ...

  6. javascript+php实现根据用户时区显示当地时间的方法

    本文实例讲述了javascript+php实现根据用户时区显示当地时间的方法.分享给大家供大家参考.具体如下: 在跨时区应用中会用到下面代码,这是以前写的一段代码. 服务器保存相关时间配置,保存形式为 ...

  7. golang之math/rand随机数

    简单的随机数生成,结合时间模块初始化种子 package main import ( "fmt" "math/rand" "time" ) ...

  8. W-D-S-链接地址

    1.程序一开始是烧写到nandflash上,设置为nandflash启动,6410片内有8K的内存,设为nandflash启动时,是从片内内存0地址开始,一上电,nandflash前面8K的内容会原原 ...

  9. [原创]使用OPENCC库进行简繁转换(C++代码)

    最近公司有一款游戏产品,字库存在问题,希望全自动进行简繁同屏自动转换的行为,减少工作量. 所以自己使用了WINDOWS自带的一些转换函数,但发现大量字出现异常,无法转换(测试iconv也发现无法转换) ...

  10. pyhon 去除列表中重复元素

    Python set() 函数 描述 set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集.差集.并集等. 语法 set 语法: class set([iterabl ...