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;
}
时间: 2024-11-11 18:56:10

HDU 6186 CS Course 前缀和,后缀和的相关文章

HDU 6186 CS Course【前后缀位运算枚举/线段树】

[前后缀枚举] #include<cstdio> #include<string> #include<cstdlib> #include<cmath> #include<iostream> #include<cstring> #include<set> #include<queue> #include<algorithm> #include<vector> #include<map

HDU 6186 CS Course(前缀+后缀)

http://acm.hdu.edu.cn/showproblem.php?pid=6186 题意:给出n个数,共有n次询问,每次询问给出一个数p,求除去第p个数后的n-1个数的&.|.^值. 思路:分别计算出&.|.^的前缀和后缀,将前缀和后缀相计算即可. 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 const int ma

hdu 6186 水

hdu 6186   CS Course 求个前后缀就好了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i) #define mes(a,b)

HDU6186 2017广西邀请赛 CS Course (前缀和后缀)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6186 思路:题目要求的删除第q个数候所有数的 & | ^和,所以提前求出前缀和后缀,每次& | ^ 前i-1个和后i+1个即可.注意a^b^b=a; #include <iostream> #include <cstdio> using namespace std; const long long maxn=1e5+10; int n,q; long long f1[m

HDU 1403 Longest Common Substring(后缀数组,最长公共子串)

hdu题目 poj题目 参考了 罗穗骞的论文<后缀数组——处理字符串的有力工具> 题意:求两个序列的最长公共子串 思路:后缀数组经典题目之一(模版题) //后缀数组sa:将s的n个后缀从小到大排序后将 排序后的后缀的开头位置 顺次放入sa中,则sa[i]储存的是排第i大的后缀的开头位置.简单的记忆就是“排第几的是谁”. //名次数组rank:rank[i]保存的是suffix(i){后缀}在所有后缀中从小到大排列的名次.则 若 sa[i]=j,则 rank[j]=i.简单的记忆就是“你排第几”

kmp(最长前缀与后缀)

http://acm.hdu.edu.cn/showproblem.php?pid=1358 Period Problem Description For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string.

自增、自减运算符的前缀和后缀

试卷中有这么一道题目: 1 2 int a = 4; (++a) += i; 求a的数值,正确答案是10. 如果你认为这道题重点只是考察运算符优先级,可能很容易得到正确的答案. 但是,考虑过为什么下面的代码无法编译么? 自己在笔试时,考虑到了关于表达式作为赋值运算符左值的问题,但是自己确实又对重载"++"操作符的实现机制和函数原型不很了解,就误认为"a++"和"++a"这两种写法都不能作为赋值运算符左值,从而以为这道题出错了,或者故意考察这一点,

hdu 4416 Good Article Good sentence (后缀数组)

题目大意: 给出一个A串和很多个B串,求出A中有多少个子串,是所有的B中没有出现的. 思路分析: 后缀数组的作用很容易的求出来整个串中不同的子串个数. 现在要求的是A中不同的,且在B中没有出现过的. 先把AB 串全部连接,跑一遍suffix array.然后求出有多少个不同的子串. 然后再单独用B 串跑 suffix array.再求出单独在B 中有多少个不同的 子串. 然后结果就是 ans1 - ans2 ... 需要注意的问题就是,连接的时候需要把每一个串后面加一个特殊符.但是求不同串的时候

HDU 3613 Best Reward(求前后缀回文 拓展KMP or Manacher)

题目大意: 给个字符串X,要把X分成两段T1,T2,每个字母都有一个对应的价值,如果T1,T2是回文串(从左往右或者从右往左读,都一样),那么他们就会有一个价值,这个价值是这个串的所有字母价值之和,如果不是回文串,那么这串价值就为0.问最多能获得多少价值? 思路: 把字符串X逆序后得到字符串Y 让X去匹配Y ,匹配的长度满足extend[i] + i == len,  len=|X|.    的那么X与y的匹配部分是回文串,这不难理解,画图即可 总复杂度是O(n),由于这是求前缀和后缀的回文,用