2012-11-11 18:04:35Morris

[UVA][ST] 12532 - Interval Product

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 XIxXI+1x ... xXJ-1xXJ 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 affect 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 first 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$ le$N, K$ le$105). The second line contains N integers Xi that represent the initial values of the sequence ( -100$ le$Xi$ le$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$ le$I$ le$N and -100$ le$V$ le$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$ le$I$ le$J$ le$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 -1C 1 10P 1 4C 3 7P 2 2C 4 -5P 1 45 91 5 -2 4 3P 1 2P 1 5C 4 -5P 1 5P 4 5C 3 0P 1 5C 4 -5C 4 -5

Sample Output 

0+-+-+-0

線段樹-

記錄區間負的個數、以及有沒有零即可。
 

#include <stdio.h>
int A[100005];
int ST[262144][2];
void build(int k, int l, int r) {
    if(l == r) {
        ST[k][1] = (A[l] == 0);
        ST[k][0] = A[l] < 0;
        return ;
    }
    if(l < r) {
        int m = (l+r)/2;
        build(k<<1, l, m);
        build(k<<1|1, m+1, r);
        ST[k][0] = ST[k<<1][0]+ST[k<<1|1][0];
        ST[k][1] = ST[k<<1][1]|ST[k<<1|1][1];
    }
}
void update(int k, int l, int r, int qx, int qv) {
    if(l == r && l == qx) {
        A[l] = qv;
        ST[k][1] = (A[l] == 0);
        ST[k][0] = A[l] < 0;
        return;
    }
    int m = (l+r)/2;
    if(qx <= m)
        update(k<<1, l, m, qx, qv);
    else
        update(k<<1|1, m+1, r, qx, qv);
    ST[k][0] = ST[k<<1][0]+ST[k<<1|1][0];
    ST[k][1] = ST[k<<1][1]|ST[k<<1|1][1];
}
int neg, has;
void query(int k, int l, int r, int ql, int qr) {
    if(l == ql && r == qr) {
        neg += ST[k][0];
        has |= ST[k][1];
        return;
    }
    int m = (l+r)/2;
    if(qr <= m) {
        query(k<<1, l, m, ql, qr);
    } else if(ql > m) {
        query(k<<1|1, m+1, r, ql, qr);
    } else {
        query(k<<1, l, m, ql, m);
        query(k<<1|1, m+1, r, m+1, qr);
    }
}
int main() {
    int n, k, i, x, y;
    char cmd[2];
    while(scanf("%d %d", &n, &k) == 2) {
        for(i = 1; i <= n; i++)
            scanf("%d", &A[i]);
        build(1, 1, n);
        while(k--) {
            scanf("%s %d %d", cmd, &x, &y);
            if(cmd[0] == 'C') {
                update(1, 1, n, x, y);
            } else {
                neg = 0, has = 0;
                query(1, 1, n, x, y);
                if(has)
                    printf("0");
                else if(neg&1)
                    printf("-");
                else
                    printf("+");
            }
        }
        puts("");
    }
    return 0;
}

fakewen 2013-10-09 13:12:08

所以是他給的測知用到A[100000th]所以爆了?
奇怪的是 我在PTT發文的code當時WA現在卻AC...
BTW我一直都開的比你還大我開
int A[1000000];
int ST[2621440][2];
當時WA現在卻AC
而且"我都沒有初始化"!

fakewen 2013-10-08 23:20:20

根據寫法不保證 m+1 <= r ? 不會嗎?
1.build有判斷式保障l<r,故m<r -> m+1<=r
2.update 只要input是正常的輸入,qx都會在l和r之間,一直遞迴的過程中m都會設成(l+r)/2,故m<r -> m+1<=r
這樣的話什麼情況會"抓到上一組測資資料所遺留的訊息"呢

版主回應
是我 code 寫錯了,深感抱歉,int A[100000]; 不夠大。
要用 A[100005]。
2013-10-09 07:43:12
fakewen 2013-10-08 18:21:57

所以是只有在update裡面才會出現超界
build裡會嗎?

版主回應
都會 2013-10-08 19:06:44