HDU 6186 CS Course 典型前缀和后缀和

题意:

给你一个序列a,然后再给你q个数,表示序列a中的第几个,然后问你:
去掉这个数,其它所有的数的与,或,异或的结果分别是多少,

分析:

维护与,或,异或的前缀数组,后缀数组,直接计算即可;
详情看代码。

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <iomanip>
#define maxn 100005
#define ll long long int
#define debug cout<<"***********"<<endl;
using namespace std;
int num[maxn];
int saf[maxn],sof[maxn],sxf[maxn];//前缀
int sar[maxn],sor[maxn],sxr[maxn];//后缀
int main(){
    int n,q;
    while(~scanf("%d %d",&n,&q)){
        for(int i = 1; i <= n ;i++){
            scanf("%d",&num[i]);
        }
        saf[1] = sof[1] = sxf[1] = num[1];
        for(int i = 2; i <= n ;i++){
            saf[i] = num[i] & saf[i-1];
            sof[i] = num[i] | sof[i-1];
            sxf[i] = num[i] ^ sxf[i-1];
        }
        sar[n] = sor[n] = sxr[n] = num[n];
        for(int i = n-1; i > 0; i--){
            sar[i] = num[i] & sar[i+1];
            sor[i] = num[i] | sor[i+1];
            sxr[i] = num[i] ^ sxr[i+1];
        }
        int a;
        while(q--){
            scanf("%d",&a);
            if(a == 1){
                printf("%d %d %d\n",sar[a+1],sor[a+1],sxr[a+1]);
            }
            else if(a == n){
                printf("%d %d %d\n",saf[a-1],sof[a-1],sxf[a-1]);
            }else{
                printf("%d %d %d\n",(saf[a-1] & sar[a+1]),(sof[a-1] | sor[a+1]),(sxf[a-1] ^ sxr[a+1]));

            }
        }

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/shensiback/article/details/80105008