bestcoder#32 1002 哈希+后缀数组

bestcoder#32 1002 哈希+后缀数组

Negative and Positive (NP)

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1161    Accepted Submission(s): 59

Problem Description

When given an array (a0,a1,a2,?an−1) and an integer K, you are expected to judge whether there is a pair (i,j)(0≤i≤j<n) which makes that NP−sum(i,j) equals to K true. Here NP−sum(i,j)=ai−ai+1+ai+2+?+(−1)j−iaj

Input

Multi test cases. In the first line of the input file there is an integer T indicates the number of test cases.
In the next 2∗T lines, it will list the data for each test case.
Each case occupies two lines, the first line contain two integers n and K which are mentioned above.
The second line contain (a0,a1,a2,?an−1)separated by exact one space.
[Technical Specification]
All input items are integers.
0<T≤25,1≤n≤1000000,−1000000000≤ai≤1000000000,−1000000000≤K≤1000000000

Output

For each case,the output should occupies exactly one line. The output format is Case #id: ans, here id is the data number starting from 1; ans is “Yes.” or “No.” (without quote) according to whether you can find (i,j) which makes PN−sum(i,j) equals to K.
See the sample for more details.

Sample Input

2

1 1

1

2 1

-1 0

Sample Output

Case #1: Yes.

Case #2: No.

题意:查找是否存在sum(i,j)==K

思路:构造后缀数组d[],对sum(i,j)=d[j]-d[i-1],从n到1遍历i-1,插入d[i-1],从哈希表中查找是否存在d[i-1]+K;

注意这里不从1到n遍历j是因为项的正负是由i-1决定,所以比较方便;当然从n开始遍历j更容易理解,但不好处理正负号

题目还卡了STL的set,更坑的是还卡了scanf,我也因此学会了手写hash和读入外挂,很好的一道题

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctype.h>
#include<algorithm>
#include<cmath>
#include<set>

using namespace std;

const int maxn=1000100;
const int HM=100100;
int n,K;
int a[maxn];
long long d[maxn];

struct Hash
{
    long long date;
    Hash *next;
};Hash h[HM];

void insert(long long date,Hash *h)
{
    int t=abs(date)%HM;
    Hash *pre=&h[t],*p=pre->next;
    while(p!=NULL){
        if(p->date=date) return;
        pre=p;
        p=p->next;
    }
    p=(Hash*)malloc(sizeof(Hash));
    p->date=date;p->next=NULL;
    pre->next=p;
}

bool find(long long date,Hash *h)
{
    int t=abs(date)%HM;
    Hash *pre=&h[t],*p=pre->next;
    while(p!=NULL){
        if(p->date==date) return true;
        pre=p;
        p=p->next;
    }
    return false;
}

inline int read()
{
    char c=getchar();
    while(c!=‘-‘&&!isdigit(c)) c=getchar();
    int f=0,tag=1;
    if(c==‘-‘){
        tag=-1;
        f=getchar()-‘0‘;
    }
    else f=c-‘0‘;
    while(isdigit(c=getchar())) f=f*10+c-‘0‘;
    return f*tag;
}

int main()
{
    int T=read();
    int tag=1;
    while(T--){
        n=read();K=read();
        d[0]=0;
        for(int i=1;i<=n;i++){
            a[i]=read();
            if(i&1) d[i]=d[i-1]+a[i];
            else d[i]=d[i-1]-a[i];
        }
        for(int i=0;i<HM;i++) h[i].next=NULL;
        bool flag=0;
        for(int i=n;i>=0;i--){
            insert(d[i],h);
            if(i&1){
                if(find(d[i]-K,h)) flag=1;
            }
            else if(find(d[i]+K,h)) flag=1;
            if(flag) break;
        }
        printf("Case #%d: ",tag++);
        if(flag) printf("Yes.\n");
        else printf("No.\n");
    }
    return 0;
}

bestcoder#32_1002

时间: 2024-10-07 02:55:42

bestcoder#32 1002 哈希+后缀数组的相关文章

bestcoder#36 1002 哈希

bestcoder#36 1002 哈希 Gunner Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 726    Accepted Submission(s): 326 Problem Description Long long ago, there is a gunner whose name is Jack. He likes t

用 二分+哈希 求后缀数组

个人感觉后缀数组的板子太难背了,听了小火车讲二分+哈希可以实现求后缀数组,貌似很好理解,代码如下. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector>

POJ 2774 后缀数组 || 二分+哈希

Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 35607   Accepted: 14275 Case Time Limit: 1000MS Description The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to him these days

bestcoder#43 1002 在数组中找两个数的和取模的最大值 二分

bestcoder#43 1002 在数组中找两个数的和取模的最大值  二分 pog loves szh II Accepts: 97 Submissions: 834 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description Pog and Szh are playing games. There is a sequence with n number

POJ2774 后缀自动机&amp;后缀数组

http://poj.org/problem?id=2774 题目大意就是给两个字符串,求最长公共子串.好像可以哈希切掉,但是为了练一练后缀数组以及学一学后缀自动机,我用不同方法终于A掉了这道题. 后缀数组:就是求出height数组然后扫一遍,求出满足条件的最大值(满足条件是指height所指的两个后缀要没有公共部分),是后缀数组的水题 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 usin

谢特——后缀数组+tire 树

题目 [题目描述] 由于你成功地在 $ \text{1 s} $ 内算出了上一题的答案,英雄们很高兴并邀请你加入了他们的游戏.然而进入游戏之后你才发现,英雄们打的游戏和你想象的并不一样…… 英雄们打的游戏是这样的:首先系统会产生(**注意不一定是随机产生**)一个字符串,然后每个英雄就会开始根据自己分到的任务计算这个字符串的某些特征,谁先算出自己的答案谁就是胜者. 由于打游戏的英雄比较多,因此英雄们分到的任务也就可能很奇怪.比如你分到的这个任务就是这样: 定义这个字符串以第 $ i $ 个字符开

【tyvj1860】后缀数组

描述 我们定义一个字符串的后缀suffix(i)表示从s[i]到s[length(s)]这段子串.后缀数组(Suffix array)SA[i]中存放着一个排列,满足suffix(sa[i])<suffix(sa[i+1]) 按照字典序方式比较定义height[i]表示suffix(sa[i])与suffix(sa[i-1])之间的最长公共前缀长度,其中height[1]=0你的任务就是求出SA和height这两个数组.字符串长度<=200000 输入格式 一行,为描述中的字符串(仅会出现小写

【转】HDU 6194 string string string (2017沈阳网赛-后缀数组)

转自:http://blog.csdn.net/aozil_yang/article/details/77929216 题意: 告诉你一个字符串和k , 求这个字符串中有多少不同的子串恰好出现了k 次. 思路: 后缀数组. 我们先考虑至少出现k 次的子串, 所以我们枚举排好序的后缀i (sa[i]) . k段k 段的枚举. 假设当前枚举的是 sa[i]~sa[i + k -1] 那么假设这一段的最长公共前缀  是L 的话. 那么就有L 个不同的子串至少出现了k次. 我们要减去至少出现k + 1次

后缀数组 DC3构造法 —— 详解

学习了后缀数组,顺便把DC3算法也看了一下,传说中可以O(n)复杂度求出文本串的height,先比较一下倍增算法和DC3算法好辣. DC3 倍增法 时间复杂度 O(n)(但是常数很大)   O(nlogn)(常数较小) 空间复杂度   O(n)    O(n) 编程复杂度    较高   较低 由于在时间复杂度上DC3的常数比较大,再加上编程复杂度比较高,所以在解决问题的时候并不是最优选择.但是学到了后缀数组还是补充一下的好点. DC3算法的实现: 1:先把文本串的后缀串分成两部分,第一部分是后