CF308C-Sereja and Brackets-(线段树+括号匹配)

题意:给出一段括号,多次询问某个区间内能匹配多少括号。

题解:线段树,结构体三个属性,多余的左括号l,多余的右括号r,能够匹配的括号数val。

当前结点的val=左儿子的val+右儿子的val+min(左儿子的l,右儿子的r)。原本匹配好的括号数加上多余的可以匹配的括号。

同时在左右儿子的l和r累加后减去新匹配的括号数。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const double PI=acos(-1);

struct node
{
    int l;
    int r;
    int val;
};
node sum[1000086*4];
char s[1000086];
int n,m,L,R;


void build(int l,int r,int rt)
{
    if(l==r)///底层的只有一个括号,不需要管val
    {
        if(s[l]=='(')
            sum[rt].l++;
        else
            sum[rt].r++;
        return;
    }
    int mid=(l+r)/2;
    build(l,mid,rt*2);
    build(mid+1,r,rt*2+1);
    int minn=min( sum[rt*2].l,sum[rt*2+1].r );
    sum[rt].val=sum[rt*2].val+sum[rt*2+1].val+minn;
    sum[rt].l=sum[rt*2].l+sum[rt*2+1].l-minn;
    sum[rt].r=sum[rt*2].r+sum[rt*2+1].r-minn;
}

node query(int l,int r,int rt)
{
    if( L<=l && r<=R )
        return sum[rt];
    int mid=(l+r)/2;

    node ans1={0,0,0},ans2={0,0,0};///必须要定义值,否则如果有一个if语句进不去,相加过程出错
    if( L<=mid ) ans1=query(l,mid,rt*2);
    if( R>mid ) ans2=query(mid+1,r,rt*2+1);
    int minn2=min(ans1.l,ans2.r);
    return { ans1.l+ans2.l-minn2, ans1.r+ans2.r-minn2, ans1.val+ans2.val+minn2 };
}


int main()///CF380C
{
    while(scanf("%s",s+1)!=EOF)
    {
        memset(sum,0,sizeof(sum));
        n=strlen(s+1);
        scanf("%d",&m);
        build(1,n,1);
        while(m--)
        {
            scanf("%d%d",&L,&R);
            printf("%d\n",query(1,n,1).val*2);
        }
    }
    return 0;
}
CF308C

 

转载于:https://www.cnblogs.com/shoulinniao/p/11323104.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
括号匹配算法是指检查给定字符串中的括号是否匹配的算法。其中,栈是实现该算法的常用数据结构。在遍历字符串时,我们可以将左括号入栈,当遇到右括号时,再将栈顶元素弹出。如果弹出的左括号与当前右括号匹配,或者栈已空而遇到右括号,则说明括号匹配。 以下是使用 C 语言实现括号匹配算法的代码: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAX_SIZE 100 // 定义栈结构体 typedef struct { char data[MAX_SIZE]; int top; } Stack; // 初始化栈 void initStack(Stack* s) { s->top = -1; } // 判断栈是否为空 bool isEmpty(Stack* s) { return s->top == -1; } // 判断栈是否已满 bool isFull(Stack* s) { return s->top == MAX_SIZE - 1; } // 入栈 void push(Stack* s, char c) { if (isFull(s)) { fprintf(stderr, "Stack is full!\n"); exit(EXIT_FAILURE); } s->data[++s->top] = c; } // 出栈 char pop(Stack* s) { if (isEmpty(s)) { fprintf(stderr, "Stack is empty!\n"); exit(EXIT_FAILURE); } return s->data[s->top--]; } // 括号匹配算法 bool checkBrackets(char* str) { Stack s; initStack(&s); for (int i = 0; str[i] != '\0'; i++) { if (str[i] == '(' || str[i] == '[' || str[i] == '{') { push(&s, str[i]); } else if (str[i] == ')' || str[i] == ']' || str[i] == '}') { if (isEmpty(&s)) { return false; } char c = pop(&s); if ((str[i] == ')' && c != '(') || (str[i] == ']' && c != '[') || (str[i] == '}' && c != '{')) { return false; } } } return isEmpty(&s); } // 测试括号匹配算法 int main() { char str[MAX_SIZE]; printf("Enter a string with brackets: "); scanf("%s", str); if (checkBrackets(str)) { printf("Brackets are matched!\n"); } else { printf("Brackets are not matched!\n"); } return 0; } ``` 在上面的代码中,我们首先定义了一个栈结构体,包含一个字符数组和一个栈顶指针。然后,我们定义了几个用于操作栈的函数,包括初始化栈、入栈、出栈、判断栈是否为空或已满等。最后,我们实现了括号匹配算法,使用栈来判断字符串中的括号是否匹配。在 main 函数中,我们通过用户输入一个字符串来测试括号匹配算法的正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值