• 【牛客CSP-S提高组赛前集训营1】C


    题目大意:

    题目链接:https://ac.nowcoder.com/acm/contest/1100/C

    小w喜欢打牌,某天小w与dogenya在一起玩扑克牌,这种扑克牌的面值都在1到n,原本扑克牌只有一面,而小w手中的扑克牌是双面的魔术扑克(正反两面均有数字,可以随时进行切换),小w这个人就准备用它来出老千作弊。小w想要打出一些顺子,我们定义打出一个l到r的顺子需要面值为从l到r的卡牌各一张。小w想问问你,他能否利用手中的魔术卡牌打出这些顺子呢?


    思路:

    巧妙。
    想象如果一张牌的两个数字分别为x,yx,y,我们将xxyy连边,那么最终就会形成几堆连通块。
    如果一个连通块是一棵树,那么由于每一条边都可以选一个数字,那么显然不可以把这个连通块里的所有数字都选择上。
    所以我们记录每一个连通块的边数、最大值和最小值,如果maxminsizemax-mingeq size,那么久不可能构成一个minmaxminsim max的顺子,也就是所有包含[min,max][min,max]的询问都不可以选择成功。
    那么将每一棵树按照最小值排序,设last[i]last[i]表示从ii开始最多可以接到多少的顺子,那么从mm枚举到1,在每一个minimingeq i的区间内取最小的maxmax,那么last[i]=max1last[i]=max-1
    然后就可以每次询问O(1)O(1)回答了。


    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N=100010;
    int m,n,sum,pos,l,r,father[N],maxn[N],minn[N],size[N],last[N];
    
    struct node
    {
    	int l,r;
    }q[N];
    
    bool cmp(node x,node y)
    {
    	return x.l<y.l;
    }
    
    int find(int x)
    {
    	return x==father[x]?x:father[x]=find(father[x]);
    }
    
    int main()
    {
    	//freopen("ex.in","r",stdin);
    	//freopen("ans.txt","w",stdout);
    	scanf("%d%d",&m,&n);
    	for (int i=1;i<=m;i++)
    		father[i]=maxn[i]=minn[i]=i;
    	for (int i=1,x,y;i<=n;i++)
    	{
    		scanf("%d%d",&x,&y);
    		x=find(x); y=find(y);
    		if (x!=y)
    		{
    			maxn[x]=max(maxn[x],maxn[y]);
    			minn[x]=min(minn[x],minn[y]);
    			size[x]+=size[y]+1;
    			father[y]=x;
    		}
    		else size[x]++;
    	}
    	for (int i=1;i<=m;i++)
    		if (father[i]==i && size[i]<=maxn[i]-minn[i])
    			q[++sum].l=minn[i],q[sum].r=maxn[i];
    	sort(q+1,q+1+sum,cmp);
    	pos=m;
    	for (int i=m;i>=1;i--)
    	{
    		for (;q[sum].l==i;sum--)
    			pos=min(pos,q[sum].r-1);
    		last[i]=pos;
    	}
    	scanf("%d",&m);
    	while (m--)
    	{
    		scanf("%d%d",&l,&r);
    		if (last[l]>=r) printf("Yes
    ");
    			else printf("No
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    BZOJ1864: [Zjoi2006]三色二叉树
    2019牛客全国多校训练四 I题 string (SAM+PAM)
    2019杭电多校第二场
    HDU5919 Sequence II(主席树)
    2019牛客全国多校训练三 题解
    2019牛客多校第二场
    2019 杭电多校第一场 题解
    2019 牛客全国多校一
    POJ3261 Milk Patterns(后缀数组)
    POJ1743 Musical Theme (后缀数组 & 后缀自动机)最大不重叠相似子串
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998014.html
Copyright © 2020-2023  润新知