ACM-ICPC Live Archive 6139 - Interval Product (线段树-点更新)

题目: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=572&page=show_problem&problem=4150


It's normal to feel worried and tense the day before a programming contest. To relax, you went out for
a drink with some friends in a nearby pub. To keep your mind sharp for the next day, you decided to
play the following game. To start, your friends will give you a sequence of N integers X1; X2; : : : ; XN.
Then, there will be K rounds; at each round, your friends will issue a command, which can be:
a change command, when your friends want to change one of the values in the sequence; or
a product command, when your friends give you two values I, J and ask you if the product
XI XI+1 : : : XJ1 XJ is positive, negative or zero.
Since you are at a pub, it was decided that the penalty for a wrong answer is to drink a pint of
beer. You are worried this could a ect you negatively at the next day's contest, and you don't want
to check if Ballmer's peak theory is correct. Fortunately, your friends gave you the right to use your
notebook. Since you trust more your coding skills than your math, you decided to write a program to
help you in the game.
Input
Each test case is described using several lines. The rst line contains two integers N and K, indicating
respectively the number of elements in the sequence and the number of rounds of the game (1
N; K 10
5
). The second line contains N integers Xi that represent the initial values of the sequence
(100 Xi 100 for i = 1; 2; : : : ; N). Each of the next K lines describes a command and starts with
an uppercase letter that is either `C' or `P'. If the letter is `C', the line describes a change command, and
the letter is followed by two integers I and V indicating that XI must receive the value V (1 I N
and 100 V 100). If the letter is `P', the line describes a product command, and the letter
is followed by two integers I and J indicating that the product from XI to XJ , inclusive must be
calculated (1 I J N). Within each test case there is at least one product command.
Output
For each test case output a line with a string representing the result of all the product commands in
the test case. The i-th character of the string represents the result of the i-th product command. If the
result of the command is positive the character must be `+' (plus); if the result is negative the character
must be `-' (minus); if the result is zero the character must be `0' (zero).
Sample Input
4 6
-2 6 0 -1
C 1 10
P 1 4
C 3 7
P 2 2
C 4 -5
P 1 4
5 9
1 5 -2 4 3
P 1 2
P 1 5
C 4 -5
P 1 5
P 4 5
C 3 0
P 1 5
C 4 -5
C 4 -5
Sample Output
0+-
+-+-0

题意:

给n个数,标号为1~n,有m个操作,操作“C a b”为将第a个数修改为b,操作“P  a  b” 为问第a个数到第b个数的乘积是正数、负数、还是零。若为正数则输出"+",负数则输出“-”,为零则输出“0”。

思路:

单点更新,输入的时候把所有的正数以1代替,负数以-1代替,0仍是0。操作“C a  b”中,若第a个数是和b同符号的那就不用修改,否则修改。

#include <cstdio>
#include <algorithm>
using namespace std;

#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 111111;
int ans[maxn<<2]={0};
int flag,s;
int aa(int x)
{
    if(x>0)return 1;
    else if(x<0)return -1;
    else return 0;
}
void PushUP(int rt) {
    ans[rt] = ans[rt<<1]*ans[rt<<1|1];
}
void build(int l,int r,int rt) {
    if (l == r) {
            int x;
        scanf("%d",&x);
         ans[rt]=aa(x);
        return ;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    PushUP(rt);
}
void update(int p,int x,int l,int r,int rt) {
    if (l == r) {

        if(aa(ans[rt])!=aa(x))
        {
            flag=1;
            ans[rt]=aa(x);
        }
        return ;
    }
    int m = (l + r) >> 1;
    if (p <= m) update(p , x , lson);
    else update(p , x , rson);
    if(flag)PushUP(rt);
}
void query(int L,int R,int l,int r,int rt) {
    if (L <= l && r <= R) {
        s*=ans[rt];
        return ;
    }
    int m = (l + r) >> 1;
    if (L <= m&&s!=0)query(L , R , lson);
    if (R > m&&s!=0) query(L , R , rson);
}
int main() {
    int n , m;
    while (~scanf("%d%d",&n,&m))
    {
        build(1 , n , 1);
        while (m --)

        {
            char op[2];
            int a , b;
            scanf("%s%d%d",op,&a,&b);
            if (op[0] == 'P')
            {
                s=1;
                query(a , b , 1 , n , 1);
                if(s==0)printf("0");
                else if(s==1)printf("+");
                else printf("-");
            }
            else
            {
                flag=0;
                update(a , b , 1 , n , 1);
            }
        }
        printf("\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值