表达式解析[笛卡尔树]

2178 表达式运算Cuties

时间限制: 1 s

空间限制: 32000 KB

题目等级 : 大师 Master

题解

查看运行结果

题目描述 Description

给出一个表达式,其中运算符仅包含+,-,*,/,^要求求出表达式的最终值

数据可能会出现括号情况 还有可能出现多余括号情况

数据保证不会出现>maxlongint的数据

数据可能回出现负数情况

输入描述 Input Description

仅一行,即为表达式

输出描述 Output Description

仅一行,既为表达式算出的结果

样例输入 Sample Input

(2+2)^(1+1)

样例输出 Sample Output

16

数据范围及提示 Data Size & Hint

表达式总长度<=30



就是练习一下笛卡尔树

多余括号太坑了,这个程序还没有处理()-1

负数我在前面加了一个0

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N=35,MOD=10007;
typedef long long ll;
int n;
char s[N];
struct node{
    int lc,rc;
    char op;
    ll num;
    node():lc(0),rc(0),num(0){}
}t[N];
int w[N],root,cnt=0;
void build(){
    int p=0;
    for(int i=1;i<=n;i++){//printf("i %d %c\n",i,s[i]);
        if(s[i]==‘(‘) {p++;continue;}
        if(s[i]==‘)‘) {p--;continue;} 

        if(s[i]==‘+‘|| (s[i]==‘-‘&&i!=1&&s[i-1]!=‘(‘)  ) w[++cnt]=p*4+1,t[cnt].op=s[i];
        else if(s[i]==‘*‘||s[i]==‘/‘) w[++cnt]=p*4+2,t[cnt].op=s[i];
        else if(s[i]==‘^‘) w[++cnt]=p*4+3,t[cnt].op=s[i];
        else{
            if(s[i]==‘-‘){//cout<<"p";
                w[++cnt]=p*4+4;
                t[cnt].op=‘a‘;t[cnt].num=0;
                w[++cnt]=p*4+1,t[cnt].op=‘-‘;
                if(s[i+1]<‘0‘||s[i+1]>‘9‘) continue;
                i++;
            }
            //printf("num %d %c\n",i,s[i]);

            w[++cnt]=p*4+4;
            ll x=0;
            while(s[i]>=‘0‘&&s[i]<=‘9‘) x=x*10+s[i]-‘0‘,i++;
            i--;
            t[cnt].num=x; t[cnt].op=‘a‘;
        }

    //printf("build %d %d %c  %d\n",cnt,w[cnt],t[cnt].op,t[cnt].num);
    }

    int st[N],top=0;
    for(int i=1;i<=cnt;i++){
        int k=top;
        while(k>0&&w[st[k]]>=w[i]) k--;
        if(k) t[st[k]].rc=i;
        if(k<top) t[i].lc=st[k+1];
        st[++k]=i;
        top=k;//printf("st %d %c %d\n",top,t[st[top]].op,w[st[top]]);
    }
    root=st[1];
}
inline ll fpow(ll a,ll b){
    ll ans=1;
    for(;b;b>>=1,a*=a)
        if(b&1) ans*=a;
    return ans;
}
ll cal(int u){
    char c=t[u].op;
    if(c==‘a‘) return t[u].num;

    ll t1=cal(t[u].lc),t2=cal(t[u].rc);//printf("cal %d  %d %c %d\n",u,t1,c,t2);
    if(c==‘+‘) return t1+t2;
    if(c==‘-‘) return t1-t2;
    if(c==‘*‘) return t1*t2;
    if(c==‘/‘) return t1/t2;
    if(c==‘^‘) return fpow(t1,t2);
}
int main(){
    scanf("%s",s+1); n=strlen(s+1);
    build();
    printf("%lld",cal(root));
}
时间: 2024-11-03 19:28:21

表达式解析[笛卡尔树]的相关文章

NOIP2011pj表达式的值[树形DP 笛卡尔树]

题目描述 对于1 位二进制变量定义两种运算: 运算的优先级是: 先计算括号内的,再计算括号外的. “× ”运算优先于“⊕”运算,即计算表达式时,先计算× 运算,再计算⊕运算.例如:计算表达式A⊕B × C时,先计算 B × C,其结果再与 A 做⊕运算. 现给定一个未完成的表达式,例如+(*_),请你在横线处填入数字0 或者1 ,请问有多少种填法可以使得表达式的值为0 . 输入输出格式 输入格式: 输入文件名为exp.in ,共 2 行. 第1 行为一个整数 L,表示给定的表达式中除去横线外的运

hdu 5412 CRB and Queries(线段树套笛卡尔树 - 动态区间第k大)

题目链接:hdu 5412 CRB and Queries 首先对所有出现过的值排序,建立线段树,每个线段树的节点是一棵笛卡尔树,笛卡尔树记录区间下标值. #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; #define lson(x) (x<<1) #define rson(x) ((x<<

笛卡尔树cartesian tree

笛卡尔树cartesian tree 笛卡尔树是一种特定的二叉树数据结构,可由数列构造,在范围最值查询.范围top k查询(range top k queries)等问题上有广泛应用.它具有堆的有序性,中序遍历可以输出原数列.笛卡尔树结构由Vuillmin(1980)[1]在解决范围搜索的几何数据结构问题时提出.从数列中构造一棵笛卡尔树可以线性时间完成,需要采用基于栈的算法来找到在该数列中的所有最近小数. 定义 无相同元素的数列构造出的笛卡尔树具有下列性质: 结点一一对应于数列元素.即数列中的每

POJ-2201-Cartesian Tree(笛卡尔树)

Description Let us consider a special type of a binary search tree, called a cartesian tree. Recall that a binary search tree is a rooted ordered binary tree, such that for its every node x the following condition is satisfied: each node in its left

[COGS 2421] [HZOI 2016] 简单的Treap 笛卡尔树

笛卡尔树就是你给两维限制,一维堆R,一维二叉搜索树K,平地拔起一棵Treap,最广范的应用:用LCA求区间最值,建Treap,还有个什么范围top k我表示并不会查都查不到.它最妙最高的地方在于用栈来建树:我们可以先排序K然后一个个插入,那么我们都是最右端,横容易被卡,那么我们不从上到下,我们从下到上,用栈维护,那就把时间复杂度从O(n^2)降到O(n),具体过程见下图从图一到图二就是这么一个过程,我们在把K为13的点插入时要找到一个合适的位置,上比他大,下比他小(假设大根堆) 下面见代码 #i

POJ 2559 Largest Rectangle in a Histogram ——笛卡尔树

[题目分析] 本来是单调栈的题目,用笛卡尔树可以快速的水过去. 把每一个矩阵看成一个二元组(出现的顺序,高度). 然后建造笛卡尔树. 神奇的发现,每一个节点的高度*该子树的大小,就是这一块最大的子矩阵的可能解. 用二元组的第一个下标来限制,使它们在一块儿,然后堆的性质又限制了宽度以及高度. 计算,取最值即可. [代码] #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath&g

POJ-1785-Binary Search Heap Construction(笛卡尔树)

Description Read the statement of problem G for the definitions concerning trees. In the following we define the basic terminology of heaps. A heap is a tree whose internal nodes have each assigned a priority (a number) such that the priority of each

4-09. 笛卡尔树(25)(ZJU_PAT)

题目链接:http://www.patest.cn/contests/ds/4-09 笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2.首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树则大.其次所有结点的K2关键字满足优先队列(不妨设为最小堆)的顺序要求,即该结点的K2值比其子树中所有结点的K2值小.给定一棵二叉树,请判断该树是否笛卡尔树. 输入格式说明: 输入首先给出正整数N(<=1000),为树中结点的个数.随后N行,每行给出一个结点的信息,

笛卡尔树 POJ ——1785 Binary Search Heap Construction

相应POJ 题目:点击打开链接 Binary Search Heap Construction Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 9075   Accepted: 2566 Description Read the statement of problem G for the definitions concerning trees. In the following we define the basic