2021东北四省赛部分题解
链接
A
推个组合数式子就完事了。
C
树形dp。和题解做法一模一样。可能只有这一种做法吧。
D
每个数至多进行log次lowbit操作,然后lowbit操作就是乘2。线段树完事。
E
阅读理解半天给我整蒙了。直接6p=p+2p+3p。
I
签到。
J
百度搜索罗德里格旋转公式。我既不知道也不会手推,活该凉凉。
K
离线并查集。
L
- 巨麻烦,写了半天,我太菜了。
- 对第一个字符串的反串建造。然后剩余个字符串的反串在上跑一跑,打个标记,就把公共子串解决了。
- 下面是第小部分。容易发现按照字典序贪心遍历树就能把字符串的反串的子串排序,这其实也是对反串建造的初衷吧。原因就是字典图上的边是在字符串尾部添加字符, 树是在字符串首加字符,但是同一个节点的子串的后缀是相同,但前缀是不同的,因此要建立反串。有点绕,画出的理解下。记录每个节点代表的子串的字典序区间即可。
- 查询就直接在前缀和数组中二分查找即可。
- 注意多解输出最靠左的细节即可。
//感想:这个题需要对sam有比较透彻的理解才能快速写完
#include<bits/stdc++.h>
using namespace std ;
struct Sam
{string s ;int last , cnt ;long long x ;vector<vector<int>> tr ;vector<int> nxt ;vector<int> len ;vector<int> in ;queue<int> q ;vector<int> pos ;vector<int> num ;vector<pair<long long , int>> res ; //u , Lvector<vector<int>> g ;vector<int> p ;vector<int> mx ;vector<int> label ;void init(){last = cnt = 1 ;int up1 = s.size() * 2 + 10 ;int up2 = 30 ; //字符集大小tr.resize(0) ;tr.resize(up1 , vector<int>(up2 , 0)) ;nxt.resize(0) ;nxt.resize(up1 , 0) ;len.resize(0) ;len.resize(up1 , 0) ;in.resize(0) ;in.resize(up1 , 0) ;pos.resize(0) ;pos.resize(up1 , -1) ;num.resize(0) ;num.resize(up1 , 0) ;res.resize(0) ;g.resize(0) ;g.resize(up1 , vector<int>(up2 , 0)) ;p.resize(0) ;p.resize(up1 , 1000000) ;label.resize(0) ;label.resize(up1 , 0) ;mx.resize(0) ;mx.resize(up1 , 0) ;while(!q.empty()) q.pop() ;x = 0 ;}void add(int c , int id){int p = last , np = ++ cnt ;pos[np] = id ;last = np , len[np] = len[p] + 1 ;for( ; p && !tr[p][c] ; p = nxt[p]) tr[p][c] = np ;if(!p) nxt[np] = 1 ;else{int q = tr[p][c] ;if(len[p] + 1 == len[q]) nxt[np] = q ;else{int nq = ++ cnt ;pos[nq] = id ;len[nq] = len[p] + 1 ;tr[nq].assign(tr[q].begin() , tr[q].end()) ;nxt[nq] = nxt[q] , nxt[q] = nxt[np] = nq ;for( ; tr[p][c] == q ; p = nxt[p]) tr[p][c] = nq ;}}}void build(){int t = s.size() ;for(int i = 0 ; i <= t - 1 ; i ++) add(s[i] - 'a' , i) ;for(int i = 1 ; i <= cnt ; i ++) p[i] = len[i] ;}void mark(string s , int t){int now = 1 ;int y = 0 ;vector<int> v ;for(int i = 0 ; i < (int)s.size() ; i ++){int c = s[i] - 'a' ;while(tr[now][c] == 0 && now > 1) now = nxt[now] , y = len[now] ;if(tr[now][c] > 1){now = tr[now][c] ;y ++ ;mx[now] = max(mx[now] , y) ;if(label[now] != t){label[now] = t ;v.push_back(now) ;int d = now ;while(nxt[d] > 1 && label[nxt[d]] != t){d = nxt[d] ;label[d] = t ;v.push_back(d) ;}}}}sort(v.begin() , v.end() , [&](int a , int b){return len[a] > len[b] ;}) ;for(auto c : v){num[c] ++ ;p[c] = min(p[c] , mx[c]) ;mx[nxt[c]] = max(mx[nxt[c]] , mx[c]) ;mx[c] = 0 ;}}void build_tree(int t){// for(int i = 1 ; i <= cnt ; i ++) cout << i << ' ' << p[i] << '\n' ;// for(int i = 1 ; i <= cnt ; i ++)// for(int j = 0 ; j < 26 ; j ++)// if(tr[i][j] > 1)// cout << "??? " << i << ' ' << j << ' ' << tr[i][j] << '\n' ;for(int i = 1 ; i <= cnt ; i ++) in[nxt[i]] ++ ;for(int i = 1 ; i <= cnt ; i ++) if(in[i] == 0) q.push(i) ; while(!q.empty()){int u = q.front() ;q.pop() ;pos[nxt[u]] = max(pos[nxt[u]] , pos[u]) ;if(nxt[u] >= 1){int i = pos[u] - len[nxt[u]] ;int c = s[i] - 'a' ;g[nxt[u]][c] = u ;}in[nxt[u]] -- ;if(in[nxt[u]] == 0) q.push(nxt[u]) ;}}void dfs(int u , int t){for(int i = 0 ; i < 26 ; i ++){int v = g[u][i] ;if(v > 0){if(num[v] == t){res.push_back({x + 1 , v}) ;x += p[v] - len[nxt[v]] ;}dfs(v , t) ; }}}void cal(int t){dfs(1 , t) ;}int rev(int x){return s.size() - 1 - x ;}void solve(int k){if(k > x){cout << "-1\n" ;return ;}auto it = upper_bound(res.begin() , res.end() , pair<long long , int>{k , 1000000000}) ;it -- ;int L = (*it).first ;int u = (*it).second ;int id = k - L + 1 ;int ans1 = pos[u] - len[nxt[u]] - id + 1 ;int ans2 = pos[u] ;cout << rev(ans2) << ' ' << rev(ans1) + 1 << '\n' ;}
} sam ;
int main()
{std::ios::sync_with_stdio(false) , cin.tie(0) ;int T ;cin >> T ;while(T --){int n ;cin >> n ;cin >> sam.s ;reverse(sam.s.begin() , sam.s.end()) ;sam.init() ;sam.build() ;for(int i = 2 ; i <= n ; i ++){string s ;cin >> s ;reverse(s.begin() , s.end()) ;sam.mark(s , i - 1) ;}sam.build_tree(n - 1) ;sam.cal(n - 1) ;int q ;cin >> q ;while(q --){int k ;cin >> k ;sam.solve(k) ;}}return 0 ;//you should actually read the stuff at the bottom before submitting or in the confusion
}
/* stuff you should look for* long long* array bounds* init* ios* special cases (n=1?)* do smth instead of nothing and stay organized* WRITE STUFF DOWN* DON'T GET STUCK ON ONE APPROACH* DON'T GET STUCK ON ONE PROBLEM
*/
M
模拟。
2021东北四省赛部分题解相关推荐
- 2018东北四省赛 Store The Matrix (矩阵)
2018东北四省赛 Store The Matrix (矩阵) 题目描述 Given a matrix M with r rows and c columns. It is obviously tha ...
- 2021蓝桥杯省赛b题解
近几年蓝桥杯再也不是暴力杯了,但是可以很好的锻炼自己的代码水平,可以以赛促学,不要老看代码,比赛后时写代码速度也很重要! 空间 计组基础题:256MB=256 * 2^20 * 8 位 所 ...
- 2018东北四省赛 Spin A Web 曼哈顿距离最小生成树
莫队的论文,讲的很清晰 问题描述:给定平面N个点,两边相连的代价为曼哈顿距离,求这些点的最小生成树 按一般想法,prime复杂度O(n^2),Kruskal复杂度O(n^2 logn),N很大时,这复 ...
- 东北四省赛H-Skyscraper-线段树的区间合并优化
题目描述: At the main street of Byteland, there will be built n skyscrapers, standing sequentially one n ...
- 2021年CCPC河南省赛部分题解
文章目录 2825: 收集金币(状态机dp) 2826: 使用技能(乘法逆元+组合数学) 2827: 欢度佳节(位运算+枚举) 2829: 闯关游戏 (DP) 2834: 小凯的书架 (树状数组+二分 ...
- 2021CCPC东北四省赛 D. Lowbit 势能线段树
传送门 分析 分析一下x+lowbit(x)x + lowbit(x)x+lowbit(x)这个操作 如果多次操作之后,那么xxx中只会有最高位存在一,这个时候再执行一次操作就会使整个数字乘二 所以, ...
- 2021第十二届蓝桥杯Python组国赛/决赛 题解
2021第十二届蓝桥杯Python组国赛/决赛 题解 前言 2021年第十二届蓝桥杯国赛/决赛,因为疫情原因没有像往年一样前往北京参赛,而是在自己学校的机房进行考试,形式上类似蓝桥杯省赛,但由于参加国 ...
- 2021.7.16模拟赛C组总结(转载XJY)
2021.7.16模拟赛C组总结 这次比赛,题虽然不难,但丝毫不影响我打挂-唉- 0+100+50+0=150 题解 T1 题目描述: 鲁宾逊先生有一只宠物猴,名叫多多.这天,他们两个正沿着乡间小 ...
- 蓝桥杯2020年第十一届C/C++B组(第二次)省赛习题题解
目录 试题A.门牌制作(拆分数字) 试题 B 既约分数(gcd) 试题C 蛇形填数(数学) 试题D 跑步锻炼(模拟) 试题E 七段码(图论+并查集) 试题F:成绩统计(格式化输出) 试题G:回文日期( ...
- 2023年福建农林大学程序设计校赛个人题解(无D解析)
2023年福建农林大学程序设计校赛个人题解(无D解析) A-这是一道原题 问题解析 从绿色材料合成到金色材料. 用 w h i l e while while 循环判断材料数是否能合成,能就合,合成后 ...
最新文章
- 百度2011招聘笔试题+答案解析
- BZOJ1146[CTSC2008]网络管理——出栈入栈序+树状数组套主席树
- 【初学者必读】:前端工程师的知识体系
- 【飞秋】SQL Server性能调教系列(4)--Profiler(上)
- jar包与aar包的区别
- 【git】git如何添加本地不是git的项目到Git库中
- 没来得及整理的一些网站
- 亡命逃窜---三维搜索
- IOS 关于扬声器和听话筒的设置 ----自己试验过的,可以达到扩音器和听筒播放的效果...
- FreeSurfer和FSL的安装和使用(脑部图像去除头骨+对图像和label同时进行仿射对齐)教程
- 差分 离散化 (线段树优化lazy标记)2018ICPC SouthEastern Fishermen
- 如何利用ps制作一张全景图?
- Linux usb设备驱动(2)--- usbmouse.c 源码分析
- python函数关键字参数传递_Python给函数传递不定关键字的参数
- GMAT Sentence Correction(2): 修饰语的一些相关问题研究
- (冒泡排序) Problem: 并列排名
- 城市燃气管网无线监测方案
- 移动硬盘里面的文件怎么恢复
- Microsoft Word 2019 for mac(word mac)
- ubuntu18.04 禁止nouveau 并安装NVIDIA显卡驱动
热门文章
- 运维工程师那些尴尬的瞬间
- 2020全国高校计算机能力挑战赛(word模拟题)
- 程序员必上的20大网站
- nosqlbooster 延长试用日期
- 使用do文件进行仿真时出现“failed tofind ‘glbl’in hierarchical name ‘/glbl/GSR‘“的解决办法
- 图片信息用浏览器显示:data:image/png;base64,+图片内容
- 有哪些PDF分割工具?建议收藏这些工具
- 如何提高阅读源代码能力
- ubuntu 20 安装手册
- 全球创见者共话企业韧性 金蝶“数字员工”惊艳亮相