24h購物| | PChome| 登入
2012-11-11 18:04:35| 人氣3,961| 回應6 | 上一篇 | 下一篇

[UVA][ST] 12532 - Interval Product

推薦 0 收藏 0 轉貼0 訂閱站台

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;
}

台長: Morris
人氣(3,961) | 回應(6)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 教育學習(進修、留學、學術研究、教育概況) | 個人分類: UVA |
此分類下一篇:[UVA][建樹] 11234 - Expressions
此分類上一篇:[UVA][Trie] 12506 - Shortest Names

fakewen
你好 可以請問一下為什麼不直接for loop直接count負數有幾個
而是用ST[]來統計 這樣有什麼好處嗎?
2013-10-02 21:57:20
版主回應
操作複雜度問題,for loop O(n),Segment O(logn)
2013-10-03 07:23:00
fakewen
那請問這題用的是top-down 還是 bottom-up 的segment tree呢?
2013-10-05 01:26:57
版主回應
top-down
2013-10-05 10:30:32
fakewen
可以在請問一下 build一開始設的初始直是為了防止什麼地方的超界呢? 我一直看不出來..
2013-10-08 10:27:47
版主回應
ST[k][1] = ST[k<<1][1]|ST[k<<1|1][1];
ST[k<<1|1][1] -> 使用 [m+1, r]。
根據寫法不保證 m+1 <= r。
在 update 中,ST[k][1] = ST[k<<1][1]|ST[k<<1|1][1];
便會抓到上一組測資資料所遺留的訊息。
2013-10-08 17:17:27
fakewen
所以是只有在update裡面才會出現超界
build裡會嗎?
2013-10-08 18:21:57
版主回應
都會
2013-10-08 19:06:44
fakewen
根據寫法不保證 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
這樣的話什麼情況會"抓到上一組測資資料所遺留的訊息"呢
2013-10-08 23:20:20
版主回應
是我 code 寫錯了,深感抱歉,int A[100000]; 不夠大。
要用 A[100005]。
2013-10-09 07:43:12
fakewen
所以是他給的測知用到A[100000th]所以爆了?
奇怪的是 我在PTT發文的code當時WA現在卻AC...
BTW我一直都開的比你還大我開
int A[1000000];
int ST[2621440][2];
當時WA現在卻AC
而且"我都沒有初始化"!
2013-10-09 13:12:08
是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文