zoukankan      html  css  js  c++  java
  • [CSPS2019] 括号树

    当年我就是死在这个题目上面,错失一等奖
    隔着这么久再来做思路还是很清晰的
    一个树形动态规划
    如果是 ( :dp[u]=dp[fa];
    如果是 ):dp[u]=dp[fa]+x;
    其中x是加入)后多出来的字串数,经分析可得x就是连续的括号数
    连续的括号可以是( )( (()) )【算2个】
    我们就要维护一个pre数组
    记得要回溯,这里我直接记录栈层就可以避免退栈的过程

    #include<bits/stdc++.h>
    using namespace std;
    #define lowbit(x) x&(-x)
    #define ll long long
    const int maxn=5e5+5;
    int n;
    char c[maxn];
    ll dp[maxn],pre[maxn];
    int sk[maxn];
    vector<int>Q[maxn];
    void calc(int u,int now){
    	for(int i=0;i<Q[u].size();i++){
    		int to=Q[u][i],tmp;
    		int top=now;
    		if(c[to]=='('){
    		dp[to]=dp[u];
    		sk[++top]=to;
    		if(c[u]==')')
    		pre[to]=pre[u];
    		else pre[to]=0;
    		}else {
    			if(top){
    				//pd=1;
    				tmp=sk[top];
    				//cout<<"tep="<<tmp<<endl;
    				top--;
    				pre[to]=pre[tmp]+1;
    			}
    			else pre[to]=0;
    			dp[to]=dp[u]+pre[to];
    		}
    		calc(to,top);
    	}
    }
    int main(){
    	//freopen("B.in","r",stdin);
    	cin>>n;
        for(int i=1;i<=n;i++)cin>>c[i]; 
        for(int i=2,fa;i<=n;i++)cin>>fa,Q[fa].push_back(i);
        if(c[1]=='(')
    	    sk[1]=1;
        calc(1,c[1]=='('?1:0);
        ll sum=0;
        for(ll i=2;i<=n;i++){
    	sum^=(i*dp[i]);
    	//if(i<=20)cout<<"dp[i]="<<dp[i]<<endl;
    	}//,
        cout<<sum<<endl;
    	return 0;
    }
    /*
    10
    ()(()()())
    1 2 3 4 5 6 7 8 9
    */
  • 相关阅读:
    vue移动端滚动插件BetterScroll
    vue商品推荐信息展示 案例
    css吸顶效果
    vue TabControl案例
    首页导航栏样式 案例
    HO引擎近况20210713
    go定时器--timer
    go定时器--Ticker
    Go测试--main测试
    Spring 核心技术 AOP 实例
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/15660695.html
Copyright © 2011-2022 走看看