信友队 2023 游记
几乎没睡着。上午讲主定理和复杂度分析,根本不会,用递归树和单点乱搞,甚至还上去讲了一下。然后讲了 CF949E,
下午是模拟赛。由于一直在调 CF949E,晚了
给出长为
的数组 ,求前 大的乘积。
。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,a[N],b[N];
priority_queue<pair<int,pair<int,int>>>q;
signed main(){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;++i){
cin>>a[i];
}
for(int i=1;i<=n;++i){
cin>>b[i];
}
sort(b+1,b+1+n,greater<int>());
for(int i=1;i<=n;++i){
q.push({a[i]*b[1],{1,i}});
}
for(int i=1;i<=n;++i){
pair<int,pair<int,int>>p=q.top();
q.pop();
cout<<p.first<<' ';
q.push({a[p.second.second]*b[p.second.first+1],{p.second.first+1,p.second.second}});
}
}
给出
个点的树,根为 。点有点权 ,有两种操作:
, 。
,查询 到根路径上的点的点权和。
这不是树剖模板题吗?过了样例,兴致勃勃交了一发结果爆
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,m,a[N],d[N],sz[N],f[N],t[N],h[N],dfn[N],cnt,bit[N];
vector<int>g[N];
void modify(int x,int k){
for(int i=x;i<=n;i+=i&(-i)){
bit[i]+=k;
}
}
int query(int x){
int ret=0;
for(int i=x;i;i-=i&(-i)){
ret+=bit[i];
}
return ret;
}
void dfs1(int u,int fa){
sz[u]=1;
for(int v:g[u]){
if(v^fa){
d[v]=d[u]+1;
dfs1(v,f[v]=u);
sz[u]+=sz[v];
}
}
}
void dfs2(int u,int fa){
for(int v:g[u]){
if(v^fa){
if((sz[v]<<1)>sz[u]){
t[h[u]=v]=t[u];
}else{
t[v]=v;
}
dfs2(v,u);
}
}
}
void dfs3(int u,int fa){
dfn[u]=++cnt;
modify(cnt,a[u]);
if(h[u]){
dfs3(h[u],u);
}
for(int v:g[u]){
if((v^fa)&&(v^h[u])){
dfs3(v,u);
}
}
}
int Query(int x){
int ret=0;
while(x){
ret+=query(dfn[x])-query(dfn[t[x]]-1);
x=f[t[x]];
}
return ret;
}
signed main(){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;++i){
cin>>a[i];
}
for(int i=1,u,v;i^n;++i){
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs1(1,0);
dfs2(t[1]=1,0);
dfs3(1,0);
for(int op,x,v;m--;){
cin>>op>>x;
if(op&1){
cin>>v;
modify(dfn[x],v);
}else{
cout<<Query(x)<<'\n';
}
}
}
然后
给出
个点的序列 ,求出最长的波形序列长度(即对于非两侧的数均大于或小于其两边的数)。
, 。
像 dp。设以
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,h[N],bit[6][N*10],f[N][2],ans=1;
void modify(int id,int x,int k){
for(int i=x;i<=1e6+2;i+=i&(-i)){
bit[id][i]=max(bit[id][i],k);
}
}
int query(int id,int x){
int ret=0;
for(int i=x;i;i-=i&(-i)){
ret=max(bit[id][i],ret);
}
return ret;
}
int main(){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;++i){
cin>>h[i];
++h[i];
f[i][0]=f[i][1]=1;
}
for(int i=1;i<=n;++i){
f[i][0]=max(f[i][0],query(1,1e6+1-h[i])+1);
f[i][1]=max(f[i][1],query(0,h[i]-1)+1);
modify(0,h[i],f[i][0]);
modify(1,1e6-h[i]+2,f[i][1]);
}
for(int i=1;i<=n;++i){
ans=max({ans,f[i][0],f[i][1]});
}
cout<<ans;
}
给出长度为
的字符串 和长度为 的字符串 。从左至右依次选取 个 的不相交子串,然后将它们依次首尾相连。求出使得连接后的串等于 的方案数,模 。
, 。
又是 dp,还是计数。以为自己要寄。还是硬着头皮推了一下方程。设
考虑是否选取
真的寄了吗?发现第二类转移是一个求区间和的形式。具象成网格图,就是过格子
测一发样例,挂得离谱。啊,每次求
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1005,M=205;
const ll mod=1e9+7;
ll f[N][M][M],s[N][M];
int n,m,K,pip[N][M];
string A,B;
signed main(){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin>>n>>m>>K>>A>>B;
A=' '+A;
B=' '+B;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
bool ok=1;
for(int k=1;k<=min(i,j);++k){
if(A[i-k+1]^B[j-k+1]){
pip[i][j]=k-1;
ok=0;
break;
}
}
if(ok){
pip[i][j]=min(i,j);
}
}
}
for(int i=0;i<=n;++i){
f[i][0][0]=1;
}
/*for(register int i=1;i<=n;++i){
for(register int j=1;j<=m;++j){
for(register int k=1;k<=min({K,j,i});++k){
f[i][j][k]+=f[i-1][j][k];
f[i][j][k]%=mod;
int y,res=0;
for(register int p=1;p<=min(i,j)&&A[i-p+1]==B[j-p+1];++p){
f[i][j][k]+=f[i-p][j-p][k-1];
res+=f[i-p][j-p][k-1];
f[i][j][k]%=mod;
y=p;
}
cout<<i<<' '<<j<<' '<<k-1<<' '<<res<<'\n';
}
}
}*/
for(int k=1;k<=min({n,m,K});++k){
memset(s,0,sizeof s);
for(int i=k-1;i<=n;++i){
for(int j=k-1;j<=m;++j){
s[i][j]=f[i][j][k-1]+(i&&j?s[i-1][j-1]:0);
s[i][j]%=mod;
//cout<<i<<' '<<j<<' '<<k-1<<' '<<s[i][j]<<'\n';
}
}
for(int i=k;i<=n;++i){
for(int j=k;j<=m;++j){
f[i][j][k]+=f[i-1][j][k];
f[i][j][k]%=mod;
f[i][j][k]+=s[i-1][j-1]-(i-pip[i][j]&&j-pip[i][j]?s[i-pip[i][j]-1][j-pip[i][j]-1]:0)+mod;
f[i][j][k]%=mod;
}
}
}
cout<<f[n][m][K];
}
但是老师说本来要卡
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1005,M=205;
const ll mod=1e9+7;
ll f[N][M],s[N][M],g[N][M];
int n,m,K,pip[N][M];
string A,B;
signed main(){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin>>n>>m>>K>>A>>B;
A=' '+A;
B=' '+B;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
bool ok=1;
for(int k=1;k<=min(i,j);++k){
if(A[i-k+1]^B[j-k+1]){
pip[i][j]=k-1;
ok=0;
break;
}
}
if(ok){
pip[i][j]=min(i,j);
}
}
}
for(int i=0;i<=n;++i){
f[i][0]=1;
}
/*for(register int i=1;i<=n;++i){
for(register int j=1;j<=m;++j){
for(register int k=1;k<=min({K,j,i});++k){
f[i][j][k]+=f[i-1][j][k];
f[i][j][k]%=mod;
int y,res=0;
for(register int p=1;p<=min(i,j)&&A[i-p+1]==B[j-p+1];++p){
f[i][j][k]+=f[i-p][j-p][k-1];
res+=f[i-p][j-p][k-1];
f[i][j][k]%=mod;
y=p;
}
cout<<i<<' '<<j<<' '<<k-1<<' '<<res<<'\n';
}
}
}*/
for(int k=1;k<=min({n,m,K});++k){
for(int i=0;i<=n;++i){
for(int j=0;j<=m;++j){
g[i][j]=f[i][j];
f[i][j]=0;
}
}
memset(s,0,sizeof s);
for(int i=k-1;i<=n;++i){
for(int j=k-1;j<=m;++j){
s[i][j]=g[i][j]+(i&&j?s[i-1][j-1]:0);
s[i][j]%=mod;
//cout<<i<<' '<<j<<' '<<k-1<<' '<<s[i][j]<<'\n';
}
}
for(int i=k;i<=n;++i){
for(int j=k;j<=m;++j){
f[i][j]+=f[i-1][j];
f[i][j]%=mod;
f[i][j]+=s[i-1][j-1]-(i-pip[i][j]&&j-pip[i][j]?s[i-pip[i][j]-1][j-pip[i][j]-1]:0)+mod;
f[i][j]%=mod;
}
}
}
cout<<f[n][m];
}
总结一下,
继续调 CF949E,还是老样子 /fn。老师让我上去讲一下
晚自习打了把初赛,阅读程序是啥啊。/kk。根本看不懂 /lb。不过完善程序板的要死 /cf。测出来居然有
上午讲的二分,给了一堆神仙题。先是 CF1016E。一开始题目看反了 /cf。不过做法是差不多的。一开始只会
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】