Codeforces 380C Sereja and Brackets

来源:互联网 发布:69直播提示网络不给力 编辑:程序博客网 时间:2024/05/20 04:13



两种做法。

树状数组的做法:

事先将所有的查询存下来,这样从左往右求值的时候就不会被查询区间右边的括号所影响了。

代码:

#include<bits/stdc++.h>#define pb push_back#define fi first#define se secondusing namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int, int> PII;const double PI = acos(-1.0);const double eps = 1e-10;int dcmp(double x) { if(fabs(x) < eps) return 0; else return x<0?-1:1; }const int INF = 0x3f3f3f3f;const int N = 1e6+5;char str[N];int ans[N], c[N], n;stack<int> S;struct node {    int x, y, id;    bool operator < (const node& a) const { return y<a.y; }}a[N];int lowbit(int x) { return x&-x; }void add(int x, int d) {    while(x <= n) {        c[x] += d;        x += lowbit(x);    }}int sum(int x) {    int ret = 0;    while(x > 0) {        ret += c[x];        x -= lowbit(x);    }    return ret;}int main() {    memset(c, 0, sizeof(c));    int m;    scanf("%s", str);    cin >> m;    n = strlen(str);    for(int i = 0; i < m; i++) scanf("%d%d", &a[i].x, &a[i].y), a[i].id = i;    sort(a, a+m);    int tot = 0, k = 0;    for(int i = 0; i < n; i++) {        if(!S.empty() && str[i]==')' && str[S.top()]!=str[i]) {            tot += 2;            add(S.top()+1, 2);            S.pop();        }        else S.push(i);//        printf("%d %d %d\n", i, k, a[k].y);        while(k<m && i==a[k].y-1) {            ans[a[k].id] = tot-sum(a[k].x-1);            k++;        }    }    for(int i = 0; i < m; i++) printf("%d\n", ans[i]);    return 0;}

线段树的做法:

建树以及查询中区间合并的时候考虑会新增括号即可。

代码:

#include<bits/stdc++.h>#define pb push_back#define fi first#define se second#define lc o<<1#define rc o<<1|1using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int, int> PII;const double PI = acos(-1.0);const double eps = 1e-10;int dcmp(double x) { if(fabs(x) < eps) return 0; else return x<0?-1:1; }const int INF = 0x3f3f3f3f;const int N = 1e6+5;char str[N];int ql, qr;struct node {    int lb, rb, num;    node() { lb = rb = num = 0; }}a[4*N];void build(int o, int L, int R) {    if(L == R) {        a[o].num = a[o].lb = a[o].rb = 0;        if(str[L] == ')') a[o].rb++;        else a[o].lb++;        return;    }    int M = (L+R)>>1;    build(lc, L, M);    build(rc, M+1, R);    int t = min(a[lc].lb, a[rc].rb);    a[o].num = a[lc].num+a[rc].num+t*2;    a[o].lb = a[rc].lb+a[lc].lb-t;    a[o].rb = a[rc].rb+a[lc].rb-t;}node query(int o, int L, int R) {//    printf("%d %d %d\n", o, L, R);    if(ql<=L && qr>=R) return a[o];    int M = (L+R)>>1;    node u, v;    if(ql <= M) u = query(lc, L, M);    if(qr > M) v = query(rc, M+1, R);    int t = min(u.lb, v.rb);    u.num = u.num+v.num+t*2;    u.lb = u.lb+v.lb-t;    u.rb = u.rb+v.rb-t;    return u;}int main() {    scanf("%s", str+1);    int n = strlen(str+1), m;//    printf("%d\n", n);    build(1, 1, n);    cin >> m;    while(m--) {        scanf("%d%d", &ql, &qr);        printf("%d\n", query(1, 1, n).num);    }    return 0;}


阅读全文
0 0
原创粉丝点击