LOJ #6043. 「雅礼集训 2017 Day7」蛐蛐国的修墙方案

我可以大喊一声这就是个SB题吗?

首先讲一句如果你像神仙CXR一样精通搜索你就可以得到\(80pts\)(无Subtask)的好成绩

我们考虑挖掘一下题目的性质,首先发现这是一个置换,那么我们发现这的显然会成环

然后我们发现那个度数的性质其实就是告诉你环上的点必须左右括号相间

换而言之一个环其实只有两种状态,那么我们对于每一个环进行搜索的复杂度显然就是\(O(2^{\frac{n}{2}}n)\)

那么考虑\(n=100\)要怎么卡过去。我们发现一个长度为\(2\)的环显然必须令前面的为左括号,后面为右括号

然后细细分析一下复杂度,这样只用长度\(\ge4\)的环需要搜索状态,那么复杂度就是\(2^{\frac{n}{4}} n\),足以通过此题

CODE

#include<cstdio>
#include<vector>
#include<cstdlib>
#define RI register int
#define CI const int&
using namespace std;
const int N=105;
int n,x,cur,p[N],col[N],sz[N]; vector <int> v[N]; bool c[N];
inline void check(int pfx=0)
{
    RI i; for (i=1;i<=n;++i)
    {
        pfx+=c[i]?-1:1; if (pfx<0) return;
    }
    for (i=1;i<=n;++i) putchar(c[i]?')':'('); exit(0);
}
inline void DFS(CI nw)
{
    if (nw>cur) return check(); if (sz[nw]==2)
    return (void)(c[v[nw][0]]=0,c[v[nw][1]]=1,DFS(nw+1));
    RI i; for (i=0;i<sz[nw];++i) c[v[nw][i]]=i&1; DFS(nw+1);
    for (i=0;i<sz[nw];++i) c[v[nw][i]]=(i&1)^1; DFS(nw+1);
}
int main()
{
    //freopen("C.in","r",stdin); freopen("C.out","w",stdout);
    RI i; for (scanf("%d",&n),i=1;i<=n;++i) scanf("%d",&p[i]);
    for (i=1;i<=n;++i) if (!col[i])
    {
        for (x=i,++cur;!col[x];x=p[x])
        col[x]=cur,v[cur].push_back(x),++sz[cur];
    }
    return DFS(1),0;
}

转载于:https://www.cnblogs.com/cjjsb/p/10673324.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值