25MX集训0801
T2不会
T1:
考虑点分治,把所有询问挂在分支中心
对于每一个 \(u\) 维护 \(dpU_{u,k,j}\) 表示最大值为 \(k\) ,最小值为 \(j\) 的从 \(u\) 到分支中心的最长不降子序列
同理维护 \(dpD_{u,k,j}\) 表示最大值为 \(k\) ,最小值为 \(j\) 的从 \(u\) 到分支中心的最长不升子序列
对于每一个询问求得 $ max~~{dpU_{x,i,1}+dpD_{y,k,i}} $ 即可
代码:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
#define int ll
const int N=1e5+5,K=11,Q=3e6+5;
int n,q,k;
int dpu[N][K][K],dpd[N][K][K];
int rt,siz[N],tot,mxp[N];
int fth[N][18],dep[N];
bool vis[N];
vector<pair<int,int>> G[N];
struct node
{
int x,y,pos;
};
vector<node> Que[N];
int ans[Q];
void dfs(int u,int fa)
{
fth[u][0]=fa,dep[u]=dep[fa]+1;
for(int i=1;i<=17;i++)
fth[u][i]=fth[fth[u][i-1]][i-1];
for(auto [v,_]:G[u])
if(v!=fa) dfs(v,u);
}
int lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=17;i>=0;i--)
if(dep[fth[x][i]]>=dep[y])
x=fth[x][i];
// cerr<<x<<" "<<y<<'\n';
if(x==y) return x;
for(int i=17;i>=0;i--)
{
if(fth[x][i]!=fth[y][i])
{
x=fth[x][i];
y=fth[y][i];
}
}
return fth[x][0];
}
void dfs1(int u,int fa)
{
siz[u]=1,mxp[u]=0;
for(auto [v,w]:G[u])
{
if(v==fa||vis[v]) continue;
dfs1(v,u);
siz[u]+=siz[v];
mxp[u]=max(siz[v],mxp[u]);
}
mxp[u]=max(mxp[u],tot-siz[u]);
if(mxp[u]<mxp[rt]) rt=u;
}
void clac(int u,int fa,int w)
{
for(int j=1;j<K;j++)
for(int i=j;i<K;i++)
dpu[u][j][i]=max(dpu[fa][j][i]+(i==w),dpu[u][j][i-1]);
for(int j=K-1;j;j--)
for(int i=j;i;i--)
dpd[u][j][i]=max(dpd[fa][j][i]+(i==w),dpd[u][j][i+1]);
return ;
}
void dfs2(int u,int fa)
{
for(auto [v,w]:G[u])
{
if(v==fa||vis[u]) continue;
clac(v,u,w);
dfs2(v,u);
}
return ;
}
void update(int u)
{
for(int i=1;i<K;i++)
for(int j=1;j<K;j++)
dpu[u][i][j]=dpd[u][i][j]=0;
for(auto [v,w]:G[u])
{
if(vis[v]) continue;
clac(v,u,w);
dfs2(v,u);
}
// cout<<"RT:"<<rt<<'\n';
for(auto [x,y,pos]:Que[u])
{
int mx=0;
// cerr<<"now: "<<x<<" "<<y<<'\n';
for(int i=1;i<K;i++)
{
// cerr<<i<<" U:"<<dpd[x][i][1]<<" D:"<<dpu[y][i][K-1]<<'\n';
mx=max(mx,dpd[x][i][1]+dpu[y][i][K-1]);
}
ans[pos]=mx;
}
Que[u].clear();
return ;
}
void solve(int u)
{
vis[u]=1,update(u);
for(auto [v,_]:G[u])
{
if(vis[v]) continue;
tot=siz[v],mxp[rt=0]=1e9;
dfs1(v,0),solve(rt);
}
}
void solve();
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
freopen("maze.in","r",stdin);
freopen("maze.out","w",stdout);
int c,_=1;
cin>>c;
while(_--) solve();
return 0;
}
void solve()
{
cin>>n>>q>>k;
for(int i=1;i<n;i++)
{
int u,v,w;
cin>>u>>v>>w;
G[u].push_back({v,w});
G[v].push_back({u,w});
}
mxp[rt=0]=n,tot=n,dfs1(1,0);
// cerr<<rt<<'\n';
dfs(rt,rt);
int x,y,a,b,c;
cin>>x>>y>>a>>b>>c;
for(int i=1;i<=q;i++)
{
int nx,ny;
// cin>>x>>y;nx=x,ny=y;
nx=(x*a+(ll)y*y*b+c+(ll)i*i)%n+1;
ny=((ll)x*x*a+y*b+(ll)c*c+i)%n+1;
int z=lca(nx,ny);
// cerr<<nx<<" "<<ny<<" "<<z<<'\n';
Que[z].push_back({nx,ny,i});
x=nx,y=ny;
}
solve(rt);
ll res=0;
for(int i=1;i<=q;i++)
{
// cerr<<ans[i]<<" ";
res^=(ll)i*ans[i];
}
// cerr<<'\n';
cout<<res;
for(int i=1;i<=n;i++) G[i].clear();
return ;
}

浙公网安备 33010602011771号