cf 120 c,d,e STL Non-Secret Cypher Counter Attack

c题:

建立一棵树,对于每个跟节点表示一个pair

然后子节点是pair或者int

叶子节点必然为int 

加判断一下就好了


D题:

可以想对于一个右边已经定下的点,只要前面有个数大于k个那么就可以统计这个所有之前的位置都是满足条件的

2 3 4 5 6 1 1 1.。。。。。假设k是3 那么在第三个1的位置可以匹配的个数就是2,3,4,5,6,1都可行。

首先离散化一下值,然后每次固定右边,找左边是否有大于k个的最右边位置,然后每次加上就好了

        for(int i=1;i<=n;i++)
        {
            int v=a[i];
            pos[v].pb(i);
            int sz=pos[v].size();
            //b[v]对应左边能往右到的元素在pos的位置
            while(b[v]+k<sz)
            {
                b[v]++;
            }
            mx=max(mx,(long long)pos[v][b[v]]);
            ans+=mx;
        }

其中pos表示的是当前值最右边的位置


E题:

好题啊。

e题相当于反图的运用

首先裸的方法就是一个个用并差集来维护集合。

然后想优化。

对于一个已经在集合里面的点,那么在次搜到这个节点时相当于是无用的,因为已经在一个集合里面了。这条边就相当于废边。

然后如果我们用链表的形式写的话,就相当于每次要删除这样的无用边,裸着做的话铁定TLE 数据好大啊好大啊啊啊啊。。。。

然后这里有个巧妙的方法啊啊啊。

就是用并差集维护,维护后面要访问的点,如果在一个集合,那么就可以跳过去了,每次相当于跳到下一次没有在这个集合的点的位置。

就是说如果这个点有后面要访问的点,那么就相当于我们可以直接跳过这些已经访问的点(如果前向星的话就是head的数组直接往后跳),这样优化的话就可以了。。

开始写set建边+二分的查找超时了。。。虽然查找是logn但是每次logn还是受不了

可以用vector记录每次要找的下标下次再二分往后找 这样就好了


void dfs(int u)
{
    ans[cnt].pb(u);
    f[u]=u+1;
    for(int j=0,i=find(1); i<=n; i=find(i+1))
    {
        j=lower_bound(mp[u].begin(),mp[u].end(),i)-mp[u].begin();
        if(j>=mp[u].size() || mp[u][j]>i)
            dfs(i);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值