Codeforces Gym 101190 (NEERC 2016) H. Hard Refactoring (模拟 + 树状数组)

来源:互联网 发布:宜人贷淘宝验证不了 编辑:程序博客网 时间:2024/05/16 09:53

题意

Helen had come upon a piece of code that uses a lot of “magical constants”. She found a logical expression that checks if an integer x belongs to a certain set of ranges, like the one shown below:

x >= 5 && x <= 10 ||x >= 7 && x <= 20 ||x <= 2 ||x >= 21 && x <= 25 ||x >= 8 && x <= 10 ||x >= 100

Helen does not like “magical constants”, so she decided to refactor this expression and all similar ones in such a way, that the refactored expression still has the same Boolean result for all integers x, but it uses as few integer constants in its text as possible.
Integers in this problem, including integer x, come from the range of all signed 16 bit integers starting from 215(−32768) to 2151(32767) inclusive.

解题思路

简单模拟,数字区间为 [215, 2151] ,全取为 true ,全不取为 false 。否则按最简表达式给出范围。

对于输入给的表达式,读取其表示的区间 [l, r] ,若 l <= r ,则将其在一维数轴上 [l, r] 每个数 +1

对结果判断,[215, 2151] 区间的每个数字判断其是否能够取到,并合并区间,打印若干段不连续区间即可。

对于如何快速对区间修改及单点查询,通过树状数组即可。

代码

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<fstream>using namespace std;const int BASE = 32769;const int N = 70000;int bin[N];inline int lowbit(int x) {  return x & -x;  }void add(int x, int w) {    for(int i=x;i<N;i+=lowbit(i))        bin[i] += w;}int sum(int x) {    int ret = 0;    for(int i=x;i;i-=lowbit(i))        ret += bin[i];    return ret;}void update(int x, int y, int w) {    add(x, w),  add(y+1, -w);}int main(){    freopen("hard.in", "r", stdin);    freopen("hard.out", "w", stdout);    char x[2], op[5], eop0, eop1;    int lmt, lft, rgt;    while(true)    {        lft = -32768,   rgt = 32767;        scanf(" %s %s %d", x, op, &lmt);        if(op[0] == '<')    rgt = lmt;        else    lft = lmt;        if(cin>>eop0>>eop1) {            if(eop0 == '&') {                scanf(" %c %s %d", &x, op, &lmt);                if(op[0] == '<')    rgt = min(lmt, rgt);                else    lft = max(lft, lmt);            }            if(lft <= rgt)                update(lft + BASE, rgt + BASE, 1);            if(eop0 == '&') {                if(cin>>eop0>>eop1);                else    break;            }        }        else {            if(lft <= rgt)                update(lft + BASE, rgt + BASE, 1);            break;        }    }    int cnt = 0;    lft = -BASE;    bool flg = false;    for(int i=1, val;i<=BASE + 32767;i++)    {        val = sum(i);        cnt += (val > 0 ? 1 : 0);        if(lft == -BASE && val)            lft = i-BASE;        if(lft != -BASE && val == 0) {            if(flg) printf(" ||\n");            if(lft == 1-BASE)                printf("x <= %d", i-BASE-1);            else                printf("x >= %d && x <= %d", lft, i-BASE-1);            lft = -BASE;            flg = true;        }    }    if(cnt == 0)        printf("false\n");    else if(cnt == 32768*2)        printf("true\n");    else if(lft != -BASE) {        if(flg) printf(" ||\n");        printf("x >= %d", lft);    }}
阅读全文
0 0
原创粉丝点击