question:
Accept or Reject(找字符串中特定长度的字符串,找到accept, or reject)
thought:
通俗的二次Hash函数:hash2(key) = PRIME – (key % PRIME)
PRIME一般选择小于 TABLE_SIZE 的质数
优质的二次Hash函数应该具备这些条件:
- 二次Hash函数结果不能为0
- 第二个哈希函数要可以覆盖表的每一个单元
#include <bits/stdc++.h>
using namespace std;
#define db(x) cerr<<#x<<" == "<<x<<endl
#define _ <<", "<<
const int B = 1e9+7;
//const int B = 1;
const int N = 5e5+5;
unsigned long long h[N], r[N];
int n, m;
char s[N];
int main() {
scanf("%d%d%s", &n, &m, s+1);
unsigned long long BM = 1;
for (int i = 0; i < m; i++) BM = B*BM;
for (int i = 1; i <= n; i++) {
h[i] = B*h[i-1] + s[i];
//cout << h[i] << " ";
}
//cout << endl;
for (int i = n; i > 0; i--) {
r[i] = B*r[i+1] + s[i];
//cout << r[i] << " ";
}
for (int i = m; i <= n; i++) {
if (h[i] - BM*h[i-m] == r[i-m+1] - BM*r[i+1]) {
printf("Accept\n");
return 0;
}
}
printf("Reject\n");
return 0;
}
question:
Beza's Hangover
简介:
单点修改和区间求和。
问区间和是否大于区间时间值的一半
thought:
是一道线段树题。
map需要输入后面的m个字符串,不能输入n个字符串,而不是。因为前面的n个字符不一定包含了所有种类。
#include <bits/stdc++.h>
using namespace std;
const int maxn =2e5+100;
int a[maxn];
int tree[maxn*4];
int n,m,k;
map<string,int>mp;
char s[maxn][22];
void build(int l,int r,int node)
{
if(l==r)
{
tree[node]=a[l];
return ;
}
int mid=(l+r)/2;
build(l,mid,node*2);
build(mid+1,r,node*2+1);
tree[node]=tree[node*2]+tree[node*2+1];
}
void updata(int node,int l,int r,int x,int y)
{
if(l==r)
{
tree[node]=y;
return ;
}
int mid=(l+r)/2;
if(x<=mid)
{
updata(node*2,l,mid,x,y);
}
if(x>mid)
{
updata(node*2+1,mid+1,r,x,y);
}
tree[node]=tree[node*2]+tree[node*2+1];
}
int query(int node,int l,int r,int x,int y)
{
if(l>=x&&r<=y)
{
return tree[node];
}
int mid=(l+r)/2;
int res=0;
if(x<=mid)
{
res+=query(node*2,l,mid,x,y);
}
if(y>mid)
{
res+=query(node*2+1,mid+1,r,x,y);
}
return res;
}
int main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);
// cout.tie(0);
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
}
char str[maxn];
int x;
while(m--)
{
scanf("%s%d",str,&x);
mp[str]=x;
// cout<<mp[str]<<" "<<str<<endl;
}
for(int i=1;i<=n;i++)
{
a[i]=mp[s[i-1]];
// cout<<s[i-1]<<" "<<mp[s[i-1]]<<endl;
// cout<<a[i]<<" "<<s[i-1]<<endl;
}
// cout<<endl;
build(1,n,1);
int u,v,w;
while(k--)
{
scanf("%d",&u);
if(u==1)
{
scanf("%d",&v);
scanf("%s",str);
updata(1,1,n,v,mp[str]);
}
else
{
scanf("%d%d",&v,&w);
int ans=query(1,1,n,v,w);
// printf("%d\n",ans);
if(ans>(w-v+1)*30) printf("YES\n");
else printf("NO\n");
}
}
return 0;
}
question:
Gorggeous Peter's Great Friend(找到对应的人和题答对得分)
thought:
①先想着用类来写,超时了,查找到结构体和类的区别:1. 堆栈的空间有限,对于大量的逻辑的对象,创建类要比创建结构好一些
2. 结构表示如点、矩形和颜色这样的轻量对象,例如,如果声明一个含有 1000 个点对象的数组,则将为引用每个对象分配附加的内存。在此情况下,结构的成本较低。
3. 在表现抽象和多级别的对象层次时,类是最好的选择
4. 大多数情况下该类型只是一些数据时,结构时最佳的选择②在c++中用scanf读string要带上对象的首地址,因为string 在c++中是类的形式存在的不能直接读(gnl)
#include <bits/stdc++.h>
#define MAXN 222222
using namespace std;
int C, S, P;
string tmp;
struct node {
string name;
int s;
}ha[MAXN];
map <string, int> handle;
map <string, int> prob;//时间会短
int main() {
scanf("%d%d%d", &C, &P, &S);
for(int i = 1; i <= C; i++) {
cin >> tmp;
handle[tmp] = i;//用string与int 绑定
ha[i].name = tmp;
}
for(int i = 1; i <= P; i++) {
int x;
cin >> tmp >> x;
prob[tmp] = x;
}
while(S--) {
string s1, s2, s3;
cin >> s1 >> s2 >> s3;
if(s3 == "AC") ha[handle[s1]].s += prob[s2];
}
for(int i = 1; i <= C; i++) {
cout << ha[i].name << " " << ha[i].s << endl;
}
}