test20230911
写在前面的话
今天考试心态不好,没有得分。
考场的开题顺序是顺序开题,但是在进行改题之后认为开题顺序应该是
题目描述
有一张单项选择题试卷,有
思路点拨
我们注意到
对于第
时间复杂度
题目描述
现在有一个长度为
现在有
思路点拨
我们考虑对于一个优秀的三元组
现在有了这个约束,三元组中,我们只考虑前两个元素
这个可以感性理解一下,相信还是比较好懂。
现在我们在一个区间内,我们考虑对于一个元素
时间复杂度
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-f;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int MAXN=5e5+10;
int n,q,a[MAXN];
int s[MAXN],top;
vector<int> p[MAXN];
struct node{
int r,pos;
node(int x=0,int y=0){
r=x,pos=y;
}
};
vector<node> e[MAXN];
int tmp[MAXN],t[MAXN<<2],f[MAXN<<2],tag[MAXN<<2];
void build(int i,int l,int r){
if(l==r){
t[i]=a[l];
return ;
}
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
t[i]=max(t[i<<1],t[i<<1|1]);
}
void pushup(int i){
f[i]=max(f[i<<1],f[i<<1|1]);
}
void pushdown(int i){
f[i<<1]=max(f[i<<1],t[i<<1]+tag[i]);
tag[i<<1]=max(tag[i<<1],tag[i]);
f[i<<1|1]=max(f[i<<1|1],t[i<<1|1]+tag[i]);
tag[i<<1|1]=max(tag[i<<1|1],tag[i]);
tag[i]=0;
}
void update(int i,int l,int r,int L,int R,int k){
if(L<=l&&r<=R){
f[i]=max(f[i],t[i]+k);
tag[i]=max(tag[i],k);
return ;
}
if(l>R||r<L) return ;
int mid=(l+r)>>1;
pushdown(i);
update(i<<1,l,mid,L,R,k);
update(i<<1|1,mid+1,r,L,R,k);
pushup(i);
}
int query(int i,int l,int r,int L,int R){
if(L<=l&&r<=R) return f[i];
if(l>R||r<L) return 0;
int mid=(l+r)>>1,ans;
pushdown(i);
ans=max(query(i<<1,l,mid,L,R),query(i<<1|1,mid+1,r,L,R));
pushup(i);
return ans;
}
vector<int>::iterator it;
signed main(){
freopen("fake.in","r",stdin);
freopen("fake.out","w",stdout);
n=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++){
while(top&&a[s[top]]<=a[i]){
p[s[top]].push_back(i);
top--;
}
if(top>0) p[s[top]].push_back(i);
s[++top]=i;
}
q=read();
for(int i=1;i<=q;i++){
int l=read(),r=read();
e[l].push_back(node(r,i));
}
build(1,1,n);
for(int l=n;l;l--){
for(it=p[l].begin();it!=p[l].end();it++){
int pos=(*it)*2-l;
if(pos<=n) update(1,1,n,pos,n,a[l]+a[*it]);
}
for(int i=0;i<e[l].size();i++){
int r=e[l][i].r;
tmp[e[l][i].pos]=query(1,1,n,l,r);
}
}
for(int i=1;i<=q;i++) cout<<tmp[i]<<endl;
return 0;
}
题目描述
思路点拨
考虑一个
这个东西比较好优化,我们定义权值和数组
我们注意到这个操作是可以以
一个比较naive的想法就是我们对于每两个不可以放隔板的元素之间单独做一遍
一点细节就是两个隔板之间的转移矩阵会有细微的差异,所以我们可以构造另一个矩阵
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-f;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int MAXN=1e4+10,mod=998244353;
int n,m,c,a[MAXN];
bool flag=0;
struct matrix{
int m[30][30];
matrix(int opt=0){
memset(m,0,sizeof(m));
if(opt==1){
for(int i=0;i<30;i++)
m[i][i]=1;
}
}
matrix friend operator*(const matrix &A,const matrix &B){
matrix C;
if(!flag){
for(int i=0;i<30;i++)
for(int j=0;j<30;j++)
for(int k=0;k<30;k++)
C.m[i][j]=(C.m[i][j]+A.m[i][k]*B.m[k][j])%mod;
return C;
}
else{
for(int i=0;i<30;i++)
for(int j=0;j<30;j++)
C.m[i][0]=(C.m[i][0]+A.m[i][j]*B.m[j][0])%mod;
}
return C;
}
};
int pos[30][30],tot;
void print(matrix A){
for(int i=0;i<=tot;i++,cout<<endl)
for(int j=0;j<=tot;j++)
cout<<A.m[i][j]<<" ";
cout<<endl;
}
matrix A,B,C,e;//e表示单位矩阵
matrix pw[100];//pw[i]表示矩阵A的2^i次方
//A是状态矩阵,B是一般的转移矩阵,C是转移向量
matrix qpow(matrix A,int b){
matrix Base=A,ans;
for(int i=0;i<=tot;i++)
ans.m[i][i]=1;
while(b){
if(b&1) ans=Base*ans;
Base=Base*Base;
b>>=1;
}
return ans;
}
signed main(){
freopen("paper.in","r",stdin);
freopen("paper.out","w",stdout);
n=read(),m=read(),c=read();
for(int i=1;i<=m;i++)
a[i]=read()+1;
sort(a+1,a+m+1);
m=unique(a+1,a+m+1)-a-1;
for(int i=1;i<=c;i++)
for(int j=0;j<i;j++)
pos[i][j]=++tot;
for(int i=1;i<=c;i++){
for(int j=0;j<i;j++){
if(j<i-1) B.m[pos[i][j]][pos[i][j+1]]=1;
else B.m[pos[i][j]][pos[i][0]]=1;
}
B.m[pos[i][i-1]][0]=1;
B.m[0][pos[i][i==1?0:1]]=1;
}
A.m[0][0]=B.m[0][0]=1;
pw[0]=B;
for(int i=1;i<=64;i++)
pw[i]=pw[i-1]*pw[i-1];
for(int i=1;i<=c;i++){
for(int j=0;j<i;j++){
if(j<i-1) C.m[pos[i][j]][pos[i][j+1]]=1;
else C.m[pos[i][j]][pos[i][0]]=1;
}
C.m[pos[i][i-1]][0]=1;
}
int pre=0;
flag=1;
for(int i=1;i<=m&&a[i]<n;i++){
int b=a[i]-pre-1;
for(int j=0;j<62;j++)
if(b&(1ll<<j))
A=pw[j]*A;
A=C*A;
pre=a[i];
}
int b=n-pre;
for(int j=0;j<62;j++)
if(b&(1ll<<j))
A=pw[j]*A;
cout<<A.m[0][0];
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!