hash乱搞大法好!

参考博客  https://www.cnblogs.com/henry-1202/p/8868414.html

hash可以解决很多有趣的问题例如kmp,ac自动机,马拉车,后缀数组等等

一个很大的质数ull mod = 212370440130137957ll;

基础练习hash

题目链接https://www.acwing.com/problem/content/description/140/

#include <bits/stdc++.h>

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const ll maxn = 1e6 + 7;
const ll mod = 1e9 + 7;
const ull base = 23333;
using namespace std; 

unordered_map<ll,ll> ss;

char a[maxn];
ull h[maxn];
ull f[maxn];
int main()
{
    
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    
    cin >> (a + 1);
    ll n = strlen(a + 1);
    f[0] = 1;
    for(int i = 1; i <= n; i ++)
    {
    	h[i] = h[i - 1] * base + (a[i] - '0');
    	f[i] = f[i - 1] * base;
	}
	
    ll t;
    cin >> t;
    while(t--)
    {
    	ll a,b,l,r;
    	cin >> a >> b >> l >> r;
    	if(h[b] - h[a - 1] * f[b - a + 1] == h[r] - h[l - 1] * f[r - l + 1])
    	{
    		cout << "Yes" << "\n";
		}
		else
		{
			cout << "No" << "\n";
		}
	}
	
	return 0;
}

模式匹配 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1686

ac代码如下

#include <bits/stdc++.h>

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const ll maxn = 1e6 + 7;
const ll mod = 1e9 + 7;
const ull base = 233333;
using namespace std; 

char a[maxn];
char b[maxn];
ull h1[maxn],f[maxn],h2[maxn];
int main()
{
    
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    
    ll t;
    cin >> t;
    while(t--)
    {
        cin >> (a + 1);
        ll n = strlen(a + 1);
        cin >> (b + 1);
        ll m = strlen(b + 1);
        for(int i = 1; i <= n; i ++)
        {
            h1[i] = h1[i - 1] * base + (a[i] - '0'); 
        }
        
        f[0] = 1;
        for(int i = 1; i <= m; i ++)
        {
            h2[i] = h2[i - 1] * base + (b[i] - '0');
            f[i] = f[i - 1] * base;
        }
        
        ll ans = 0;
        for(int i = 1; i + n - 1 <= m; i ++)
        {
            ll r = i + n - 1;
            if(h2[r] - h2[i - 1] * f[r - i + 1] == h1[n])
            {
                ans ++;
            }
        }
        
        cout << ans << endl;
    }

    return 0;
}

雪花问题求出最小匹配

题目链接https://www.acwing.com/problem/content/description/139/

#include <bits/stdc++.h>

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const ll maxn = 1e5 + 7;
const ll mod = 1e9 + 7;
const ull base = 23333;
using namespace std; 

unordered_map<ll,ll> ss;

ll check(ll now,ll com,vector<ll> a)
{
	ll n = a.size();
	for(int i = 0; i < a.size(); i ++)
	{
		if(a[(now + i) % n] != a[(com + i) % n])
		return a[(now + i) % n] < a[(com + i) % n];
	}
	
	return 0;
}
int main()
{
    
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    
    ll n;
    cin >> n;
    for(int i = 1; i <= n; i ++)
    {
    	ll x;
    	vector<ll>a,b,c;
    	for(int j = 1; j <= 6; j ++)
    	{
	    	cin >> x;
	    	a.push_back(x);
		}
		ll ans = 0;
    	for(int j = 1; j < 6; j ++)
    	{
    		if(check(ans,j,a))ans = j;
		}
		
		for(int j = 0; j < 6; j ++)
		{
			b.push_back(a[(ans + j) % 6]);
		}
		
		reverse(a.begin(),a.end());
		ans = 0;
    	for(int j = 1; j < 6; j ++)
    	{
    		if(check(ans,j,a))ans = j;
		}
		
		for(int j = 0; j < 6; j ++)
		{
			c.push_back(a[(ans + j) % 6]);
		}
		
		ll be = 1;
		for(int j = 0; j < 6; j ++)
		{
			if(b[j] != c[j])
			{
				if(b[j] < c[j])
				{
					be = 1;
					break;
				}
				else
				{
					be = 2;
					break;
				}
			}
		}
		
		if(be == 1)
		{
			ull ans = 0;
			for(int j = 0; j < b.size(); j ++)
			{
				ans = ans * base + b[j];
			}
			if(ss[ans] == 1)
			{
				cout << "Twin snowflakes found." << endl;
				return 0;
			}
			ss[ans] = 1;
		}
		else
		{
			ull ans = 0;
			for(int j = 0; j < c.size(); j ++)
			{
				ans = ans * base + c[j];
			}
			if(ss[ans] == 1)
			{
				cout << "Twin snowflakes found." << endl;
				return 0;
			}
			ss[ans] = 1;
		}
	}
	
	cout << "No two snowflakes are alike." << endl;
	
	return 0;
}

运用前缀 题目链接https://loj.ac/problem/2823

ac代码如下

#include <bits/stdc++.h>

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const ll maxn = 2e6 + 7;
const ll mod = 1e9 + 7;
const ull base = 131;
using namespace std; 

char a[maxn];
char b[maxn];
ull h[maxn],f[maxn];

ll get_hash(ll l,ll r)
{
	return h[r] - h[l - 1] * f[r - l + 1];
}

ll get_s(ll l,ll r,ll x)
{
	return get_hash(l,x - 1) * f[r - x] + get_hash(x + 1,r);
}
int main()
{
    
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    
    set<ll>s;
    ll n;
    cin >> n;
    cin >> (a + 1);
    if(n % 2 == 0)
    {
    	cout << "NOT POSSIBLE" << endl;
	}
	else
	{
		f[0] = 1;
		for(int i = 1; i <= n; i ++)
		{
			f[i] = f[i - 1] * base;
			h[i] = h[i - 1] * base + a[i];
		}
		
		ll pre,nxt,mark = 0;
		for(int i = 1; i <= n; i ++)
		{
			if(i <= n / 2)
				pre = get_s(1,n / 2 + 1,i);
			else
				pre = h[n / 2];	
			
			if(i <= n / 2 + 1)
				nxt = get_hash(n / 2 + 2,n);
			else
				nxt = get_s(n / 2 + 1,n,i);
			
			if(pre == nxt)
			{
				mark = i;
				s.insert(pre);
			}
		}
		
		if(s.empty())
		{
			cout << "NOT POSSIBLE" << endl;
		}
		else
		{
			if(s.size() > 1) 
			{
				cout << "NOT UNIQUE" << endl;
				return 0;
			}
			if(s.size() == 1)
			{
				if(mark <= n / 2)
				{
					for(int i = 1; i <= n / 2 + 1; i ++)
					{
						if(i != mark)
						{
							cout << a[i];
						}
					}
					cout << endl;
				}
				
				else
				{
					for(int i = n / 2 + 1; i <= n; i ++)
					{
						if(i != mark)
						{
							cout << a[i];
						}
					}
					cout << endl;
				}
			}
		}
	}
	
	return 0;
}

马拉车题目链接https://www.51nod.com/Challenge/Problem.html#!#problemId=1089

#include <bits/stdc++.h>

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const ll maxn = 1e6 + 7;
const ll mod = 1e9 + 7;
const ull base = 233333;
using namespace std; 

char a[maxn];
ull h1[maxn],f[maxn],h2[maxn];
int main()
{
    
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    
    //freopen("E://1.txt","r",stdin);
    cin >> (a + 1);
    ll n = strlen(a + 1);
	
	f[0] = 1;
	for(int i = 1; i <= n; i ++)
	{
		h1[i] = h1[i - 1] * base + (a[i] - '0');
		f[i] = f[i - 1] * base;
	} 
	
	
	for(int i = n; i >= 1; i --)
	{
		h2[i] = h2[i + 1] * base + (a[i] - '0');
	}
	
	
	ll ma = 1;
	for(int i = 1; i <= n; i ++)
	{
		if(a[i] == a[i + 1])
		{ 
			ll l1 = i;
			ll r1 = i - ma / 2 + 1;
			ll l2 = i + 1;
			ll r2 = i + 1 + ma / 2 - 1;
			ma = max(ma,(ll)2);
			while(r1 >= 1 && r2 <= n && h1[l1] - h1[r1 - 1] * f[l1 - r1 + 1] == h2[l2] - h2[r2 + 1] * f[r2 - l2 + 1])
			{
				ma = max(ma,r2 - r1 + 1);
				r1 --;
				r2 ++;
			}
		}
		if(a[i - 1] == a[i + 1])
		{
			ll l1 = i - 1;
			ll r1 = i - 1 - ma / 2 + 1;
			ll l2 = i + 1;
			ll r2 = i + 1 + ma / 2 - 1;
			ma = max(ma,(ll)3);
			while(r1 >= 1 && r2 <= n && h1[l1] - h1[r1 - 1] * f[l1 - r1 + 1] == h2[l2] - h2[r2 + 1] * f[r2 - l2 + 1])
			{
				ma = max(ma,r2 - r1 + 1);
				r1 --;
				r2 ++;
			}
		}
	}
	
	cout << ma << endl;


	return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值