只补了E,F,G题,就当作补了道EGF的题好了!
建个二叉树,然后树上DP
就很一眼吧
ll POW(ll a,ll k=P-2,ll res=1){while(k){if(k&1)res=res*a%P;a=a*a%P;k>>=1;}return res;}
const int N=1e3+10;
ll fac[N],finv[N];
void init()
{
fac[0]=1;
for(int i=1;i<N;++i)fac[i]=fac[i-1]*i%P;
finv[N-1]=POW(fac[N-1]);
for(int i=N-2;i;--i)finv[i]=finv[i+1]*(i+1)%P;
finv[0]=1;
}
int a[N];
ll C(int a,int b){return fac[a]*finv[a-b]%P*finv[b]%P;}
int root;
struct Node
{
int l,r,val,siz,lsz;
}tr[N];
int pos;
void add(int u,int val)
{
++tr[u].siz;
if(!tr[u].val){tr[u].val=val;return ;}
if(tr[u].val<val)
{
if(!tr[u].r)tr[u].r=++pos;
add(tr[u].r,val);
}
else if(tr[u].val>val)
{
if(!tr[u].l)tr[u].l=++pos;
++tr[u].lsz;
add(tr[u].l,val);
}
}
/*void print_tree(int u)
{
if(tr[u].l)dfs2(tr[u].l);
printf("%d ",tr[u].val);
if(tr[u].r)dfs2(tr[u].r);
}*/
ll dp[N];
void dfs(int u)
{
dp[u]=C(tr[u].siz-1,tr[u].lsz);
//{cout<<"check :"<<dp[u]<<" "<<tr[u].siz<<" "<<tr[u].lsz<<" "<<u<<endl;}
if(tr[u].l)
{
dfs(tr[u].l);
dp[u]=dp[u]*dp[tr[u].l]%P;
}
if(tr[u].r)
{
dfs(tr[u].r);
dp[u]=dp[u]*dp[tr[u].r]%P;
}
}
void debug(int u)
{
cout<<"now :"<<tr[u].lsz<<endl;
}
int main()
{
init();
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
memset(tr,0,sizeof(tr));
pos=1,root=1;
for(int i=1;i<=n;++i)add(root,a[i]);
//print_tree(1);
//debug();
dfs(root);
printf("%lld\n",dp[1]);
}
}
F题vp的时候想了个两个set+一个优先队列的做法,但因为时间不够就没写,最终选择了用题解的做法
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
bool st[N];
using pii=pair<int,int>;
void debug(string s){cout<<"now :"<<s<<endl;}
void debug(vector<vector<int>> mp)
{
for(int i=0;i<=9;++i)
{
if(mp[i].size())cout<<"now is :"<<i<<'\n';
for(auto v:mp[i])cout<<v<<" ";
if(mp[i].size())cout<<'\n';
}
}
void solve(string rs,int d)
{
int n=rs.size();++d;
vector<int> a(n);
for(int i=0;i<n;++i)st[i]=0;
for(int i=0;i<n;++i)a[i]=rs[i]-'0';
vector<vector<int>> mp(10),stk(10);
for(int i=0;i<=min(d,n-1);++i)stk[a[i]].push_back(i);
for(int i=0;i<n;++i)
{
if(i+d<n&&i)stk[a[i+d]].push_back(i+d);
if(st[i])continue;
for(int j=9;j>a[i];--j)
{
if(stk[j].empty()||stk[j].back()<=i)continue;
mp[j].push_back(i);
st[stk[j].back()]=1;
stk[j].pop_back();
break;
}
}
//debug(stk);
vector<priority_queue<pii,vector<pii>,greater<pii>>> heap(10);
for(int i=n-1;~i;--i)
{
if(st[i])
{
while(mp[a[i]].size()&&mp[a[i]].back()+d>=i)
{heap[a[i]].push({a[mp[a[i]].back()],mp[a[i]].back()});mp[a[i]].pop_back();}
auto v=heap[a[i]].top();
heap[a[i]].pop();
swap(rs[v.second],rs[i]);
}
}
cout<<rs<<'\n';
}
int main()
{
string s;int d;
while(cin>>s>>d)solve(s,d);
}
做个G吧,然后就G了
这种题写少了,建图建假导致debug一晚上,什么事情都没做
建了个很蠢的图是我没想到的
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N=1e2+10;
char g[N][N];
using pii=pair<int,int>;
int pos;
vector<int> e[25];
pii id[25];
int mp[N][N];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
bool st[N][N],vis[25],treasure[25],trap[25];
int n,m;
void get_graph(pii idn,int t)
{
st[idn.x][idn.y]=1;
for(int i=0;i<4;++i)
{
int x=idn.x+dx[i],y=idn.y+dy[i];
if(x<1||x>n||y<1||y>m||(g[x][y]=='#')||st[x][y])continue;
if(mp[x][y]!=-1)
{
e[t].push_back(mp[x][y]);
continue;
}
get_graph({x,y},t);
}
}
void init1()
{
pos=0;
memset(mp,-1,sizeof(mp));
memset(treasure,0,sizeof(treasure));
memset(trap,0,sizeof(trap));
for(int i=0;i<25;++i)e[i].clear();
}
bool dp[1<<22][23];
void init2()
{
for(int i=0;i<1<<pos+1;++i)for(int j=0;j<=pos;++j)dp[i][j]=0;
}
int test;
int dfs(int state,int p)
{
if(dp[state][p])return 0;
dp[state][p]=1;
int rs=0;
if(p==0)
{
int nw=state;
// cout<<"now :"<<(++test)<<endl;
// for(int i=0;i<=pos;++i)cout<<((state>>i)&1);cout<<'\n';
for(int i=1;i<=pos;++i)
{
if((state>>i&1)&&treasure[i])++rs;
if(state>>i&1)
for(int j=0;j<4;++j)
{
int x=dx[j]+id[i].x,y=dy[j]+id[i].y;
if(x<1||x>n||y>m||y<1||g[x][y]!='@')continue;
if(!(nw&(1<<mp[x][y])))
{++rs;nw|=1<<mp[x][y];}
// cout<<x<<" "<<y<<endl;
}
// if(rs==3){for(int i=0;i<=pos;++i)cout<<((state>>i)&1);cout<<'\n';}
}
}
for(auto v:e[p])
{
if((state&1<<v)&&trap[v])continue;
rs=max(dfs(state|(1<<v),v),rs);
}
return rs;
}
void debug()
{
for(int i=0;i<=pos;++i)
{
//if(e[i].size());
cout<<"now is :"<<i<<endl;
for(auto v:e[i])cout<<v<<" ";
if(e[i].size())
cout<<'\n';
}
}
void init_graph()
{
pii sta;
for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)
if((g[i][j]=='.')&&(i==1||i==n||j==1||j==m)){sta={i,j};break;}
id[0]=sta;mp[sta.x][sta.y]=0;
//cout<<"now sta: "<<sta.x<<" "<<sta.y<<endl;
for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)
if(g[i][j]!='.'&&g[i][j]!='#')
{
id[++pos]={i,j};
treasure[pos]=(g[i][j]=='@');
trap[pos]=(g[i][j]=='X');
mp[i][j]=pos;
}
for(int i=0;i<=pos;++i)
{
memset(st,0,sizeof(st));//memset(vis,0,sizeof(vis));
get_graph(id[i],i);
//if(i)e[i].push_back(0);
}
}
void solve()
{
for(int i=1;i<=n;++i)scanf("%s",g[i]+1);
init1();
init_graph();
init2();
// debug();
printf("%d\n",dfs(1,0));
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)solve();
return 0;
}