Codeforces Round #754 (Div. 2)

tip3

给定一个长度为 n 的字符串,只包含 a、b、cabc,求满足以下条件的最短的子串的长度:

  • 长度至少为2
  • aa 的数量严格大于 bb 的数量
  • aa 的数量严格大于 cc 的数量

如果无解,输出 -1

很容易想到:aa   aba  aca  abca

这三种序列如果有的话就选最优就行

但是.....考虑不全面!!

认真思考,当上述序列不存在,

abbacca

accabba就是最优情况

枚举就行

经验:贪心题:一定考虑所有情况,想全面,这很考察思维,需要锻炼

Codeforces Round #754 (Div. 2) - Virtual Judge (vjudge.net)

tip4

数学知识

先入为主

首先想到性质:

legal(u,v)当且仅当high(u)==high(v)

如果想让A这个人一定赢,下第一步,那我让任意两个节点之间都illegal不就可以了??

这样一定最优秀(不用想那么多,直接想最优的)

染色法,

把0和1的节点存着

神奇的构造!

计算出tot(0):100111001

那么我在分的时候

(以此类推)把最高位是100000000的数都拿出来,

有100000000-111111111刚好100000000个

说明如果按照这种构造方式,一定而且恰好可找到tot(0)个数,使得所有最高位分解恰好在{0}集合里

那么,万一不够呢?(n<111111111)

这就需要我们用min的一类颜色先分配,然后其他的就都给另一类就行

const int N=2000+100;
int ans[200000+100];//存每个点对应后来的哪个点
vector<int>col[3];
vector<int>belong[40];//0或者1
struct node
{
    int to,nxt;
}e[400000+100];
int tot,head[200000+100];
inline void add(int x,int y)
{
    e[++tot].to=y,e[tot].nxt=head[x],head[x]=tot;
}
inline int get(int x)
{
    int tmp=0;
    while(x)
    {
        tmp++;x>>=1;
    }
    return tmp;
}
int n;
inline void dfs(int x,int fa,int c)
{
    col[c].push_back(x);
    for(int i=head[x];i;i=e[i].nxt)
    {
        int to=e[i].to;
        if(to==fa)continue;
        dfs(to,x,c^1);
    }
}
inline void solve()
{
    tot=0;
    _f(i,0,n)head[i]=0;
    _f(i,0,31)belong[i].clear();
    _f(i,0,1)col[i].clear();
    n=re();
    _f(i,1,n)belong[get(i)].push_back(i);
    _f(i,1,n-1)
    {
        int u=re(),v=re();add(u,v);add(v,u);
    }
    dfs(1,-1,0);
    int top=col[0].size();
    int tip=get(n);
    //chu("(top)%d(tip:%d)\n",top,tip);
    f_(i,tip,1)//为什么倒着??
    {
        int num=belong[i].size();
        if(top>=num)
        {
            top-=num;
            while(num--)
            {
                ans[col[0].back()]=belong[i].back();
                //chu("ans:%d  %d\n",col[0].back(),belong[i].back());
                belong[i].pop_back();
                col[0].pop_back();
            }
        }

    }
  //  _f(i,0,1)chu("col1:%d\n",col[1][i]);
    f_(i,tip,1)
    {
        int num=belong[i].size();
        while(num--)
        {
            ans[col[1].back()]=belong[i].back();
            belong[i].pop_back();
            col[1].pop_back();
        }
    }
    _f(i,1,n)chu("%d ",ans[i]);
    chu("\n");
}
int main()
{
//    freopen("exam.txt","r",stdin);
//    freopen("a.out","w",stdout);
    int t=re();
    while(t--)solve();
    return 0;
}

 

posted on 2022-07-05 16:05  HZOI-曹蓉  阅读(19)  评论(0编辑  收藏  举报