[NOI2017]蚯蚓排队 hash
题面:洛谷
题解:
我们暴力维护当前所有队伍内的所有子串(长度k = 1 ~ 50)的出现次数。
把每个子串都用一个hash值来表示,每次改变队伍形态都用双向链表维护,并暴力更新出现次数。
现在考虑复杂度。
如果只有连接,没有断开,那么复杂度为不同的子串个数:50n(注意只要O(n)预处理前缀和后缀hash就可以做到O(1)得到一个子串的hash值)
如果有断开,那么最多就每断开一次就对应要再重连一次。所以复杂度最多增加2500 * 断开次数,而断开次数1e3....
所以复杂度就是正确的了。
此题略卡常。
如果T了一两个点,,,就多交几次吧,,,说不定哪次就过了呢?
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 201000
#define ac 10501000
#define LL long long
#define us unsigned
#define maxn 49//每边最多49个,以为另外一边至少一个
#define base 19260817//2333//直接用10???
#define bu 16777215//49999991//100000081//cket 一个质数,,,
#define mod 998244353
#define h(f) (f & bu) int n, m, top;
int v[AC], last[AC], Next[AC];
us LL hs[AC], ls[ac], p[ac];
int Head[ac * ], Next1[ac], date[ac], tot, id;
int cnt[ac]; us LL power[ac];//存下每个id对应的hash值以及出现次数
int s[AC];
char ss[ac];
//int tot, id; #define Next Next1
//inline int h(int f){
//return (((f & bu) ^ (mod >> 5)) + 1);
//} struct node{ inline void add(int f, us LL x)
{//如果x这个表上没有k这个值,那就要新开id,否则直接用原来的id
// printf("%d %llu\n", f, x);
// printf("%llu\n", x);
for(R i = Head[f]; i; i = Next[i])
if(power[date[i]] == x) {++ cnt[date[i]]; return ;}
int tmp = ++ id;
date[++ tot] = tmp, Next[tot] = Head[f], Head[f] = tot;
power[tmp] = x, cnt[tmp] = ;
} inline void del(int f, us LL x)//找到这个值并删除一个
{
for(R i = Head[f]; i; i = Next[i])
if(power[date[i]] == x) {-- cnt[date[i]]; return ;}
} inline int find(int f, us LL x)
{
for(R i = Head[f]; i; i = Next[i])
if(power[date[i]] == x) return cnt[date[i]];
return ;
}
}T;
#undef Next inline int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} void pre()
{
n = read(), m = read(), p[] = ;
for(R i = ; i <= n; i ++) v[i] = read(), T.add(h(v[i]), v[i]);//先把单个的加进去
for(R i = ; i <= n; i ++) p[i] = p[i - ] * base;//自然溢出
} us LL cal(int l, int r){//返回[l, r]的hash值
return ls[r] - ls[l - ] * p[r - l + ];
} void get_hs(int mid, bool z)//获取所有长度<= 50的,跨mid的hs值
{
for(R i = ; i <= top; i ++) ls[i] = ls[i - ] * base + s[i];
for(R i = ; i <= mid; i ++)//枚举开头
{
int lim1 = mid - i + , lim2 = top - i + ;//长度要在[lim1, lim2]的范围内
for(R len = lim1; len <= lim2; len ++)//才能保证合法
{
int r = i + len - ;
us LL x = cal(i, r);//获取区间hash值
if(z) T.add(h(x), x);
else T.del(h(x), x);
}
}
} void link1()//每次合并的时候暴力加hash值,每次最多增加1250个
{
int x = read(), y = read(), cnt = , tmp = ;//把j接到i之后
Next[x] = y, last[y] = x, top = ;
for(R i = x; i && cnt < maxn; i = last[i]) ++ cnt, tmp = i;
for(R i = tmp; i != x; i = Next[i]) s[++ top] = v[i];
s[++ top] = v[x], cnt = top;
for(R i = y; i && top - cnt != maxn; i = Next[i]) s[++ top] = v[i];
get_hs(cnt, );
} void link()//每次合并的时候暴力加hash值,每次最多增加1250个
{
int x = read(), y = read(), cnt = , tmp = ;//把j接到i之后
Next[x] = y, last[y] = x, top = ;
for(R i = x; i && cnt < maxn; i = last[i]) ++ cnt, tmp = i;
for(R i = tmp; i != x; i = Next[i]) s[++ top] = v[i];
s[++ top] = v[x], cnt = top;
for(R i = y; i && top - cnt != maxn; i = Next[i]) s[++ top] = v[i];
get_hs(cnt, );
} void cut()//每次合并的时候暴力减hash值,每次最多减少1250个,但总体很小
{
int x = read(), y = Next[x], cnt = , tmp = ;//把i和它之后的一个蚯蚓断开
last[y] = Next[x] = top = ;
for(R i = x; i && cnt < maxn; i = last[i]) ++ cnt, tmp = i;
for(R i = tmp; i != x; i = Next[i]) s[++ top] = v[i];
s[++ top] = v[x], cnt = top;
for(R i = y; i && top - cnt != maxn; i = Next[i]) s[++ top] = v[i];
get_hs(cnt, );
} void find()//处理hash值的时候暴力O(n)处理前缀hash值,然后查询的时候也O(n)遍历查询
{//因为s长度之和最多1e7....
//cin >> ss + 1, top = strlen(ss + 1);
scanf("%s", ss + ), top = strlen(ss + );
int k = read(), b = top - k + ;
for(R i = ; i <= top; i ++)
ls[i] = ls[i - ] * base + ss[i] - '';
LL ans = ;
for(R i = ; i <= b; i ++)
{
us LL x = cal(i, i + k - );
ans *= T.find(h(x), x);
//printf("!!%d ", T.find(x & bu, x));
if(ans > mod) ans %= mod;
}
//printf("\n");
printf("%lld\n", ans);
} void work()
{
for(R i = ; i <= m; i ++)
{
int opt = read();
if(opt == ) link();
else if(opt == ) cut();
else find();
}
} int main()
{
// freopen("in.in", "r", stdin);
pre();
work();
//fclose(stdin);
return ;
}
[NOI2017]蚯蚓排队 hash的更多相关文章
- 【uoj#315/bzoj4943】[NOI2017]蚯蚓排队  Hash
		
题目描述 给出 $n$ 个字符,初始每个字符单独成字符串.支持 $m$ 次操作,每次为一下三种之一: $1\ i\ j$ :将以 $i$ 结尾的串和以 $j$ 开头的串连到一起. $2\ i$ :将 ...
 - [Bzoj4943][Noi2017]蚯蚓(hash)
		
4943: [Noi2017]蚯蚓 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 237 Solved: 110[Submit][Status][D ...
 - 洛谷P3832 [NOI2017]蚯蚓排队  【链表 + 字符串hash】
		
题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为 ...
 - [NOI2017]蚯蚓排队(链表+hash)
		
这题看题面感觉挺玄学的,但其实会挂链式hash就能暴力切了,就是纸老虎,考察选手的语文水平.不过三年没写挂链hash也应该写一下了…… 首先模数设成自然溢出ull,然后挂链时的模数取2^24.然后就可 ...
 - BZOJ4943 NOI2017蚯蚓排队(哈希+链表)
		
能看懂题就能想到正解.维护所有长度不超过k的数字串的哈希值即可,用链表维护一下蚯蚓间连接情况.由于这样的数字串至多只有nk个,计算哈希值的总复杂度为O(nk),而分裂的复杂度为O(ck^2),询问复杂 ...
 - BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解
		
https://www.lydsy.com/JudgeOnline/problem.php?id=4943 http://uoj.ac/problem/315 https://www.luogu.or ...
 - bzoj4943 [Noi2017]蚯蚓排队
		
题面:http://www.lydsy.com/JudgeOnline/upload/Noi2017D1.pdf 正解:字符串$hash$. 我在考场上写了个$map$的$hash$被卡成$40$分, ...
 - P3823_[NOI2017]蚯蚓排队 哈希+脑子
		
之前就写过一遍,今天却写挂了,查了半天发现是数组名写错啦$qwq$ 观察到$K$很小,所以使得我们可以哈希(怎么什么都能哈希$qwq$).我们把长度小于等于$50$的子串扔到哈希表里,并统计出现次数, ...
 - [NOI2017]蚯蚓排队
		
嘟嘟嘟 现在看来这道题还不是特别难. 别一看到字符串就想SAM 看到\(k\)很小,所以我们可以搞一个单次修改复杂度跟\(k\)有关的算法. 能想到,每一次断开或链接,最多只会影响\(k ^ 2\)个 ...
 
随机推荐
- URL特别字符处理
			
import time,os,datetimeimport urllib3utcNow = datetime.datetime.utcnow()fifteen = utcNow +datetime.t ...
 - FTP如何通过Windows防火墙
			
将C:\Windows\SysWOW64\ftp.exe(64位系统)C:\Windows\system32\ftp.exe(32位系统)文件添加到防火墙的允许列表中即可. 注:“控制面板” -> ...
 - 移动端车牌识别/车牌OCR识别
			
周末,小编约了朋友商场shopping. 开车进地下车库时,“滴”的一声,完成车牌录入:开车离开时,扫描二维码,输入车牌,完成停车收费.小编不禁感叹科技改变生活,人工智能给生活带来的便利. 车牌自动识 ...
 - 算法笔记(c++)--完全背包问题
			
算法笔记(c++)--完全背包和多重背包问题 完全背包 完全背包不同于01背包-完全背包里面的东西数量无限 假设现在有5种物品重量为5,4,3,2,1 价值为1,2,3,4,5 背包容量为10 # ...
 - 第1章 Python基础
			
一.安装Python windows: 1.下载安装包 https://www.python.org/downloads/ 2.安装 默认安装路径:C:\python27 3.配置环境 ...
 - [笔记] mysql5.6一些编译参数
			
cmake \ -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \ -DSYSCONFDIR=/etc \ -DWITH_INNOBASE_STORAGE_ENGINE ...
 - “Hello World!团队”Beta发布—视频链接+文案+美工
			
视频链接:http://v.youku.com/v_show/id_XMzE3MjEyMzkyMA==.html?spm=a2h3j.8428770.3416059.1 文案+美工:http://ww ...
 - unknown2
			
结对作业 本次结对:211606457 郑沐榕.211406242 杨长元 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时( ...
 - Android:有关下拉菜单导航的学习(供自己参考)
			
Android:有关==下拉菜单导航==的学习 因为先前的学习都没想着记录自己的学习历程,所以该博客才那么迟才开始写. 内容: ==下拉菜单导航== 学习网站:android Spinner控件详解 ...
 - 四则运算2+psp0
			
程序要求: 1.题目避免重复 2.可定制(数量\打印方式) 3.可以一下控制参数 ① 是否有乘除法 ② 是否有括号(最多支持十个数参与运算) ③ 数值范围 ④加减有无负数 ⑤除法有无余数 分析:① 如 ...