• Souvenir Shop 解题报告


    Souvenir Shop

    魔幻题目,这谁搞得到啊...

    考场上完全sb了写了个线段树合并,想必我是个复杂度分析都没学过的入门级选手

    发现这个网格图dag它的出度最多只有2

    如果按照先走朝上的一条边进行dfs走后续遍历,就是遍历完儿子再加自己,那么dfn大于它的一定不会比它低

    然后再按照先走朝右的一个边走后续遍历,dfn2大于它的一定不会比它左

    那么它可以到达的点满足(le dfn1_i,le dfn2_i)就可以了...

    然后就是普及组随便统计一下的问题了...


    Code:

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    const int N=3e5+10;
    template <class T>
    void read(T &x)
    {
    	x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    }
    struct koito_yuu
    {
    	int dfn1,dfn2,v,now;
    	bool friend operator <(koito_yuu a,koito_yuu b){return a.dfn1==b.dfn1?a.dfn2<b.dfn2:a.dfn1<b.dfn1;}
    }yuu[N];
    int s[N],ans[N],mi[N],vis[N];
    int n,m,v[N],to[2][N],dfsclock,dx[N],dy[N];
    void add(int x,int d)
    {
    	while(x<=n) s[x]+=d,x+=x&-x;
    }
    int qry(int x)
    {
    	int ret=0;
    	while(x) ret+=s[x],x-=x&-x;
    	return ret;
    }
    void dfs1(int now)
    {
    	if(!now||vis[now]) return;
    	vis[now]=1;
    	dfs1(to[0][now]);
    	dfs1(to[1][now]);
    	yuu[now].dfn1=++dfsclock;
    }
    void dfs2(int now)
    {
    	if(!now||vis[now]) return;
    	vis[now]=1;
    	dfs2(to[1][now]);
    	dfs2(to[0][now]);
    	yuu[now].dfn2=++dfsclock;
    }
    int main()
    {
        freopen("souvenir.in","r",stdin);
        freopen("souvenir.out","w",stdout);
    	read(n),read(m);
    	for(int i=1;i<=n;i++) read(dx[i]),read(dy[i]),read(yuu[i].v),yuu[i].now=i,mi[i]=n+1;
    	for(int u,v,i=1;i<=m;i++)
    	{
    		read(u),read(v);
    		if(dx[u]==dx[v])
    		{
    			if(dy[u]>dy[v]) std::swap(u,v);
    			to[0][u]=v;
    		}
    		else
    		{
    			if(dx[u]>dx[v]) std::swap(u,v);
    			to[1][u]=v;
    		}
    	}
    	dfs1(1);
    	dfsclock=0;
    	memset(vis,0,sizeof vis);
    	dfs2(1);
    	std::sort(yuu+1,yuu+1+n);
    	for(int i=1;i<=n;i++)
    	{
    		if(mi[yuu[i].v]>yuu[i].dfn2)
    		{
    			add(mi[yuu[i].v],-1);
    			mi[yuu[i].v]=yuu[i].dfn2;
    			add(mi[yuu[i].v],1);
    		}
    		ans[yuu[i].now]=qry(yuu[i].dfn2);
    	}
    	for(int i=1;i<=n;i++) printf("%d
    ",ans[i]);
    	return 0;
    }
    

    2019.3.26

  • 相关阅读:
    2021,6,10 xjzx 模拟考试
    平衡树(二)——Treap
    AtCoder Beginner Contest 204 A-E简要题解
    POJ 2311 Cutting Game 题解
    Codeforces 990G GCD Counting 题解
    NOI2021 SDPTT D2T1 我已经完全理解了 DFS 序线段树 题解
    第三届山东省青少年创意编程与智能设计大赛总结
    Luogu P6042 「ACOI2020」学园祭 题解
    联合省选2021 游记
    Codeforces 1498E Two Houses 题解 —— 如何用结论吊打标算
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10601688.html
Copyright © 2020-2023  润新知