zr模拟赛 8 (dp)
zr模拟赛 8
你好我的朋友,现在我生病了,对不起。
23zr提高day8-测测你的计数水平
👌
首先断环为链,方法是枚举某一个点连的是那一条边。
接着设表示从左到右扫到i的时候所有区间都没有超过i的方案数。
然后发现如果当前新区间覆盖了两个相同颜色的点就寄了,但是没有就没事。
另外一种想法是令表示i之前一共能满足多少个合法的区间。
容易发现虽然决策不一样但是这个区间个数是确定的,因为如果我们把两个区间换成一个的话就寄了。
最后验证一下合法区间的数量是否等于n-1(第一个已经拿下了)
然后就做完了。
include<bits/stdc++.h>
using namespace std;\
using namespace std;
const int maxn=6e6+10;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int a[maxn];
long long ans;
int pre[maxn],nxt[maxn];
int n;
const int mod=1e9+7;
int p[maxn];
int g[maxn];
int f[maxn];
void solve(int l,int r){
int len=r-l+1;
memset(pre,0,sizeof(pre));
memset(nxt,0,sizeof(nxt));
memset(f,0,sizeof(f));
g[l-1]=1;
for(int i=l;i<=r;i++){
if(p[a[i]]) pre[i]=p[a[i]];
p[a[i]]=i;
//// cout<<pre[i]<<" " ;
}
for(int i=1;i<=n;i++) p[i]=0;
for(int i=l;i<=r;i++){
f[i]=f[i-1];
g[i]=g[i-1];
if(pre[i])
if(f[pre[i] - 1] + 1 > f[i])
{
f[i] = f[pre[i] - 1] + 1;
g[i] = g[pre[i] - 1];
}
else if(f[pre[i] - 1] + 1 == f[i]) g[i] = (g[i] + g[pre[i] - 1]) % mod;
cout<<f[i]<<" "<<a[i]<<" "<<g[i]<<endl;
}
if(f[r]==n-1 ) ans=(ans+g[r])%mod;
}
signed main(){
n=read();
for(int i=1;i<=n*3;i++){
a[i]=read();
a[i+3*n]=a[i];
}
a[1];
int fir=0,sec=0;
for(int i=2;i<=3*n;i++){
if(a[i]==a[1]) fir?sec=i:fir=i;
}
// cout<<fir<<" "<<sec<<endl;
solve(fir+1,3*n);
solve(sec+1,fir+3*n-1);
solve(2,sec-1);
cout<<ans<<endl;
}
23zr提高day8-测测你的优化水平
首先把所有节点映射到一个二维坐标系上的(x,y)。
我们可以把操作看作两个扫描线,一个删掉了x>i的所有结点,另外一个删掉了y>j的所有结点。
然后我们定义表示这个扫描线当前在(i,j)时候的最好答案。这个答案显然是确定的。
转移方程就是
前缀和优化可以做到。
这个东西呢你观察一下就发现如果的话我就直接加上不是的话就直接加上.
线段树优化一下就做完了。
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
const int maxn=2e5+10;
struct node{
int x,y,i;
}d[maxn];
int g[maxn];
int n;
bool cmp(node a,node b){
return a.x<b.x;
}
int f[maxn*4];
int lz[maxn*4];
int len;
void pushdown(int p){
lz[p<<1]+=lz[p];
lz[p<<1|1]+=lz[p];
f[p<<1]+=lz[p];
f[p<<1|1]+=lz[p];
lz[p]=0;
}
void add(int p,int l,int r,int L,int R,int v){
// cout<<p<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<v<<endl;
if(L>R) return ;
// if(f[p]>=0x3f3f3f3f) return ;
if(L<=l&&r<=R){
f[p]+=v;
// cout<<f[p]<<" "<<v<<endl;
lz[p]+=v;
return ;
}
if(lz[p]) pushdown(p);
int mid=(l+r)>>1;
if(mid>=L) add(p<<1,l,mid,L,R,v);
if(mid<R) add(p<<1|1,mid+1,r,L,R,v);
f[p]=min(f[p<<1],f[p<<1|1]);
// cout<<f[p]<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<v<<endl;
}
int get(int p,int l,int r,int L,int R){
if(L<=l&&r<=R){
return f[p];
}
if(lz[p]) pushdown(p);
int mid=(l+r)>>1;
int cnt=LLONG_MAX;
if(mid>=L) cnt=min(cnt,get(p<<1,l,mid,L,R));
if(mid<R) cnt=min(cnt,get(p<<1|1,mid+1,r,L,R));
return cnt;
}
void insert(int p,int l,int r,int x,int v){
if(l==r) {
f[p]=v;
return ;
}
pushdown(p);
int mid=(l+r)>>1;
if(mid>=x) insert(p<<1,l,mid,x,v);
else insert(p<<1|1,mid+1,r,x,v);
f[p]=min(f[p<<1],f[p<<1|1]);
}
signed main(){
n=read();
for(int i=1;i<=n;i++){
d[i].x=read(),d[i].y=read();
g[i]=d[i].y;
}
sort(d+1,d+n+1,cmp);
g[n+1]=0;
sort(g+1,g+n+2);
memset(f,0x3f,sizeof(f));
len=unique(g+1,g+n+2)-g-1;
// for(int i=1;i<=len;i++) cout<<g[i]<<" ";
for(int i=1;i<=n;i++){
d[i].i=lower_bound(g+1,g+len+1,d[i].y)-g;
// cout<<d[i].i<<" "<<d[i].y<<endl;
}
insert(1,1,len,1,0);
for(int i=1;i<=n;i++){
int y=d[i].i;
// cout<<d[i].i<<endl;
int v=get(1,1,len,1,d[i].i)+d[i].x;
// insert(1,1,n,d[i].i,v);
// cout<<2<<endl;
add(1,1,len,d[i].i+1,len,d[i].x);
// cout<<d[i].i+1<<" "<<len<<" "<<d[i].x<<endl;
// cout<<3<<endl;
add(1,1,len,1,d[i].i,d[i].y);
// cout<<1<<" "<<d[i].i<<" "<<d[i].y<<endl;
// cout<<4<<endl;
insert(1,1,len,d[i].i,v);
// cout<<d[i].i<<endl;
// for(int j=1;j<=len;j++){
// cout<<get(1,1,len,j,j)<<" ";
// }
// cout<<endl;
}
cout<<get(1,1,n,1,n)<<endl;
}
由于这一题调试了很久
所以把经验写在下面:
1.静态调试,注意线段树参数
2.return后面不能写东西
3.想好再写,思想是指导行动的方针
大道理讲完了,明天见,谢谢大家。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现