BZOJ2093 [Poi2010]Frog

    xiaoxiao2022-06-21  29

    我们发现到了一个点之后会跳到哪个点是固定的,于是整个图形成了环套树森林,得到了这棵环套树我们就能得出答案,那么我们考虑如何算距离每个点第k近的点

    发现距离一个点i第0~k近的点(第0近的点就是i自己)组成了一个包含第i个点的长度为k+1的区间,且第k近的点是区间的一个端点,那么我们维护这个区间

    i得1时区间一定是[1,k+1],那么我们考虑i++之后会对区间有什么影响,设区间左端点为q,右端点为p,那么当dis(p+1,i)<dis(q,i)时,我们要令区间右移一位,当dis(q-1,i)<=dis(p,i)时,区间要左移一位,然后我们发现不可能出现dis(q-1,i)<=dis(p,i)的情况,因为首先当i固定的时候,区间要么只进行右移,要么只进行左移,其次若dis(q-1,i)<=dis(p,i),那么一定满足dis(q-1,i-1)<=dis(p,i-1),也就说明在i-1就应该已经进行过左移了,而i-1时没有进行左移,说明这种情况不存在

    所以每次暴力把区间右移即可,复杂度O(n)

    这样我们就得出了环套树森林,我们可以对每棵环套树dfs一遍,这样对于距离环的距离>m的点能直接通过用栈记录根到当前点的所有点得出答案,而记录每个点到环的距离和环的大小以及环上每个点之后我们就能得出距离环的距离<=m的点的答案,这一步也是复杂度O(n)

    总复杂度O(n)

    #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #include<cmath> #include<algorithm> #include<iomanip> #include<vector> #include<map> #include<set> #include<bitset> #include<queue> #include<stack> using namespace std; #define MAXN 1000010 #define MAXM 1010 #define INF 1000000000 #define MOD 1000000007 #define eps 1e-8 #define ll long long char xB[1<<15],*xS=xB,*xT=xB; #define getc() (xS==xT&&(xT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xT)?0:*xS++) inline ll read() { ll x=0,f=1;char ch=getc(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();} return x*f; } struct vec{ int to; int fro; }; vec mp[MAXN]; int tai[MAXN],cnt; int n,k; ll m; ll d[MAXN]; int fa[MAXN]; int vis[MAXN],T; int siz[MAXN]; bool ic[MAXN]; int bel[MAXN]; int tot; int dep[MAXN]; int rt[MAXN]; vector<int>ps[MAXN]; int st[MAXN],tp; int ed[MAXN]; inline void be(int x,int y){ mp[++cnt].to=y; mp[cnt].fro=tai[x]; tai[x]=cnt; } ll dis(int x,int y){ return abs(d[x]-d[y]); } void find(int x){ if(bel[x]){ return ; } find(fa[x]); bel[x]=bel[fa[x]]; dep[x]=dep[fa[x]]+1; rt[x]=rt[fa[x]]; } void dfs(int x){ int i,y; st[++tp]=x; if(dep[x]>m){ ed[x]=st[tp-m]; } for(i=tai[x];i;i=mp[i].fro){ y=mp[i].to; dep[y]=dep[x]+1; bel[y]=bel[x]; rt[y]=rt[x]; dfs(y); } tp--; } int main(){ int i; n=read(); k=read(); m=read(); for(i=1;i<=n;i++){ d[i]=read(); } int p=k+1,q=1; int T=0; for(i=1;i<=n;i++){ while(p<n&&q<i&&dis(p+1,i)<dis(q,i)){ p++; q++; } if(dis(q,i)>=dis(p,i)){ fa[i]=q; }else{ fa[i]=p; } } for(i=1;i<=n;i++){ if(!vis[i]){ int x=i; T++; while(!vis[x]){ vis[x]=T; x=fa[x]; } if(vis[x]==T){ tot++; while(!ic[x]){ siz[bel[x]=tot]++; ps[tot].push_back(x); ic[x]=1; rt[x]=ps[tot].size()-1; x=fa[x]; } } } } for(i=1;i<=n;i++){ if(!ic[i]){ be(fa[i],i); } } for(i=1;i<=n;i++){ if(ic[i]){ dfs(i); } } for(i=1;i<=n;i++){ if(m<dep[i]){ printf(i==n?"%d\n":"%d ",ed[i]); }else{ printf(i==n?"%d\n":"%d ",ps[bel[i]][(rt[i]+(m-dep[i])%siz[bel[i]])%((int)ps[bel[i]].size())]); } } return 0; } /* */

    转载请注明原文地址: https://ju.6miu.com/read-1122611.html

    最新回复(0)