HDU 6186 CS Course 前缀和,后缀和

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6186

题意:给了n个数,然后有q个查询,每个查询要求我们删掉一个数,问删掉这个数后整个序列的与值,或值,异或值的和。

解法:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int n, m, a[maxn], sum1[maxn][2], sum2[maxn][2], sum3[maxn][2];

int main()
{
    while(~scanf("%d %d", &n,&m))
    {
        for(int i=1; i<=n; i++) scanf("%d", &a[i]);
        sum1[1][0] = sum2[1][0] = sum3[1][0] = a[1];
        for(int i=2; i<=n; i++){
            sum1[i][0] = sum1[i-1][0]&a[i];
            sum2[i][0] = sum2[i-1][0]|a[i];
            sum3[i][0] = sum3[i-1][0]^a[i];
        }
        sum1[n][1] = sum2[n][1] = sum3[n][1] = a[n];
        for(int i=n-1; i>=1; i--){
            sum1[i][1] = sum1[i+1][1]&a[i];
            sum2[i][1] = sum2[i+1][1]|a[i];
            sum3[i][1] = sum3[i+1][1]^a[i];
        }
        while(m--)
        {
            int idx;
            scanf("%d", &idx);
            int ans = INT_MAX;
            if(idx > 1) ans &= sum1[idx-1][0];
            if(idx < n) ans &= sum1[idx+1][1];
            printf("%d ", ans);
            ans = 0;
            if(idx > 1) ans |= sum2[idx-1][0];
            if(idx < n) ans |= sum2[idx+1][1];
            printf("%d ", ans);
            ans = 0;
            if(idx > 1) ans ^= sum3[idx-1][0];
            if(idx < n) ans ^= sum3[idx+1][1];
            printf("%d\n", ans);
        }
    }
    return 0;
}

 

posted @ 2017-09-06 17:24  zxycoder  阅读(274)  评论(0编辑  收藏  举报