zoukankan      html  css  js  c++  java
  • 【CSP2019 D1T2】【括号树】

    题面

    不再多说,想必大家都看过这个题

    思路

    我们可以手推几个满足条件的字符串
    我们发现在这些字符串里
    每个)都与离它最近的(的匹配
    所以我们维护树上每个节点到根节点中没用使用过的(的位置(nl[n]) h[i]表示以i的结尾的满足条件的串的个数

    	nl[n] = nl[fa[n]];	
    	if(value[n] == 1)
    	nl[n] = n;
    	else
    	{
    		if(nl[n] != 0)
            {
            ll f = fa[nl[n]];
            nl[n] = nl[f];
    	h[n] = 1 + h[f];//把离)最近的(使用
    		}
    	}
    

    最后因为是字串 所以需要h[i]前缀和
    (注意(1<=f_u<u)

    代码

    #include<iostream>
    #include<cstdio>
    #define ll long long
    using namespace std;
    const ll M = 500015;
    struct edge{
    	ll to,next;
    }QWQ[M];
    ll head[M],n,fa[M],value[M],h[M],nl[M],ans;
    void merge(ll x,ll y)
    {
    	QWQ[ ++QWQ[0].to ].to = x;
    	QWQ[ QWQ[0].to ].next = head[y];
    	head[y] = QWQ[0].to;
    }
    void dfs(ll n)
    {
    	nl[n] = nl[fa[n]];	
    	if(value[n] == 1)
    	nl[n] = n;
    	else
    	{
    		if(nl[n] != 0)
            {
            ll f = fa[nl[n]];
            nl[n] = nl[f];
    		h[n] = 1 + h[f];
    		}
    	}
    	for(ll i = head[n];i;i = QWQ[i].next)
    	dfs(QWQ[i].to);
    }
    int main()
    {
    	scanf("%lld",&n);
    	char c;
    	for(ll i = 1;i <= n;i++)
    	{
    		c = getchar();
    		while(c != '('&&c != ')')
    		c = getchar();
    		if(c == '(')
    		value[i] = 1;
    		if(c == ')')
    		value[i] = 2;
    	}
    	for(ll i = 2;i <= n;i++)
    	{
    		scanf("%lld",&fa[i]);
    		merge(i,fa[i]);
    	}
    	dfs(1);
    	ans = h[1];
    	for(ll i = 2;i <= n;i++)
    	{
    		ll j = i;
    		h[i] += h[fa[j]];
    		ans ^= i * h[i];
    	} 
    	cout<<ans;
    }
    
  • 相关阅读:
    第08组 Alpha冲刺 (6/6)
    第08组 Alpha冲刺 (5/6)
    第08组 Alpha冲刺 (4/6)
    第08组 Alpha冲刺 (3/6)
    第08组 Alpha冲刺 (2/6)
    第08组 Alpha冲刺 (1/6)
    第一次编程作业
    第01组 Alpha冲刺(6/6)(组长)
    第01组 Alpha冲刺总结(组长)
    第01组 Alpha冲刺 (5/6)(组长)
  • 原文地址:https://www.cnblogs.com/dixiao/p/13732759.html
Copyright © 2011-2022 走看看