首页 > 其他分享 >2024.2.26模拟赛T2题解

2024.2.26模拟赛T2题解

时间:2024-02-26 21:23:15浏览次数:22  
标签:2024.2 int 题解 top T2 tot id dfn void

题目

对询问扫描线,建出 \(PAM\) 的失配树之后,每次查询相当于,把 \(r\) 对应节点到根路径染色之后,有多少个节点的值大于 \(l\),可以树剖+ODT 实现

code

#pragma GCC optimize("Ofast", "inline", "-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
using namespace std;
#define N 400005
#define pii pair<int,int> 
#define fir first
#define sec second
int n,m;
int pos[N];
char a[N];
vector<int> G[N];
namespace PAM{
	int tot,las;
	int len[N],f[N],ch[N][27];
	int nw(int l){
		len[++tot]=l,f[tot]=0;
		return tot;
	}
	void pre(){
		tot=-1,las=0,a[0]='#';
		nw(0),nw(-1),f[0]=1;
	}
	int gt_f(int p,int i){
		while(a[i-len[p]-1]!=a[i]) p=f[p];
		return p;
	}
	void ins(int c,int i){
		int p=gt_f(las,i);
		if(!ch[p][c]){
			int q=nw(len[p]+2);
			f[q]=ch[gt_f(f[p],i)][c];
			ch[p][c]=q;
		}
		las=ch[p][c],pos[i]=las;
	}
	void build(){
		for(int i=2;i<=tot;i++){
			if(!f[i]) f[i]=1;
			G[f[i]].push_back(i);
		}
	}
}
int tot;
int sz[N],son[N],tp[N],dfn[N],fu[N];
void dfs1(int x,int fa){
	sz[x]=1;
	for(auto y:G[x]){
		if(y==fa) continue;
		dfs1(y,x);sz[x]+=sz[y];
		if(sz[son[x]]<sz[y]) son[x]=y;
	}
}
struct A{
	int l,r,col;
};
bool operator < (A x,A y){
	if(x.l!=y.l) return x.l<y.l;
	return x.r<y.r;
}
set<A> q[N];
void dfs2(int x,int fa,int top){
	//printf("%d %d %d\n",x,fa,top);
	dfn[x]=++tot,tp[x]=top,fu[x]=fa;
	if(son[x]) dfs2(son[x],x,top);
	else q[top].insert({dfn[top],dfn[x],0});
	for(auto y:G[x]){
		if(y==fa||y==son[x]) continue;
		dfs2(y,x,y);
	}
}
int c[N];
inline int lowbit(int x){
	return x&(-x);
}
void add(int x,int y){
	if(!x) return ;
	for(;x;x-=lowbit(x)) c[x]+=y;
}
int sum(int x){
	int ans=0;
	for(;x<=n;x+=lowbit(x)) ans+=c[x];
	return ans;
}
void gai(int id,int x,int y){
	while(1){
		auto it=q[id].begin();
		A p=*it;
		if(p.r>=x){
			add(p.col,-(x-p.l+1));q[id].erase(it);
			if(p.r>x) q[id].insert({x+1,p.r,p.col});
			break;
		}
		add(p.col,-(p.r-p.l+1)),q[id].erase(it);
	}
	add(y,x-dfn[id]+1);
	q[id].insert({dfn[id],x,y});
}
void upd(int x,int y){
	while(x){
		gai(tp[x],dfn[x],y);
		x=fu[tp[x]];
	}
}
int ans[N];
vector<pii > qry[N];
inline int read(){
	int num=0;
	char c=getchar();
	while(c<'0'||c>'9') c=getchar();
	while('0'<=c&&c<='9') num=num*10+c-'0',c=getchar();
	return num;
}
int main(){
	freopen("necklace.in","r",stdin);
	freopen("necklace.out","w",stdout);
	scanf("%s",a+1);
	n=strlen(a+1);
	scanf("%d",&m);
	for(int i=1,x,y;i<=m;i++){
		x=read(),y=read();
		qry[y].push_back({x,i});
	}
	PAM::pre();
	for(int i=1;i<=n;i++) PAM::ins(a[i]-'a'+1,i);
	PAM::build();
	dfs1(1,0),dfs2(1,0,1);
	for(int i=1;i<=n;i++){
		upd(pos[i],i);
		for(auto p:qry[i]) ans[p.sec]=sum(p.fir)-1;
	}
	for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
	return 0;
}

标签:2024.2,int,题解,top,T2,tot,id,dfn,void
From: https://www.cnblogs.com/hubingshan/p/18035599

相关文章

  • 2024.2.26 LGJ Round
    A给出一个\(n\)个顶点的有向图,求有多少个长度小于\(k\)的环(环可以经过重复的结点)。两个环不同当且仅当顶点序列不同。\(n\le35,k\le1e6\)。矩阵乘法模板题。枚举起点,求出走\(\lek\)步到达自己的方案数。只需要记录\(f_i\)表示以\(i\)结尾的路径个数,以及\(g_i\)......
  • 2024.2.26闲话——错误的时间复杂度
    推歌:猛独が襲う——一二三想了一个非常奇怪的逻辑。我们知道斐波那契数列是需要递推的。我们由前两个数推到第\(3\)个数的时间复杂度是\(O(1)\)。推第\(4\)个数是\(O(1)\)的基础上加\(1\)还是\(O(1)\)。然后我们以此类推下去,递推求斐波那契数列任意一项都是\(O(1)......
  • 2024.2.26模拟赛T1题解
    题目先建出圆方树,题目转换为数长度为\(2*L-1\)的路径数,长链剖分code#include<bits/stdc++.h>usingnamespacestd;#defineN2000005#definelllonglongintn,m,top,tot,cnt,L,k;intdfn[N],low[N],zhan[N],h[N];structAB{ inta,b,n;}d[N*4];voidcun(intx,int......
  • P7154 Sleeping Cows 题解
    传送门题意:给定两个数组\(a_i,b_i\),若\(a_i\leb_j\),则他俩可配对。求极大匹配的方案数。(极大不是最大,最大一定是极大)先考虑最大匹配方案数怎么求。把\(a\)和\(b\)从小到大排序。则每个\(a_i\)能匹配的\(b\)都是一段后缀,且随着\(i\)增大,这个后缀越来越小。于是从......
  • P4708 画画 题解
    先叠层甲。此解法非本题正解如果想看正解可以去看上面\(Sdchr\)或\(Log_x\)大佬的。第一眼看到此题,\(N\)个点的无标号的每个连通块有欧拉回路的图的个数。这不就是\(N\)阶赛德尔矩阵的个数吗?什么?你不知道赛德尔矩阵是什么。没关系。这东西是个很小众的东西。百度上都......
  • 2..3...4.... Wonderful! Wonderful! 题解
    2..3...4....Wonderful!Wonderful!题目描述​ 有一个元素等于其下标的数组,长度为n,对于属于区间\([1,(n-1)/2]\)的每一个数,我们称其为k,我们可以对数组进行任意次数的操作。​ 操作:选择长度为\(2*k+1\)的子序列,然后只留下最中间的那个数,删掉其他的元素。​ 我们想知道对于每个......
  • QT多线程实现-----问题解决及实现方式
    一、概述恰巧正在做一个多线程通信的项目,具体功能是与下位机交互和文件发送,在子线程中实现命令发送和文件传输。使用movetothread主要遇到以下几个问题:1.Socketnotifierscannotbeenabledordisabledfromanotherthread。2.子线程完成文件传输,发送信号......
  • P1119 灾后重建题解
    目录思路代码\(原题传送门\)思路首先先来分析一下算法,Floyd算法的时间复杂度是\(O(n^3)\)虽然很多,但在这一题里很合适。dijkstra算法用堆优化的时间复杂度是\(O(m\logn)\),在这一题里会超时。Bellman–Ford算法的时间复杂度是\(O(mn)\),会超时。所以说这一题是能用Flo......
  • 近期总结 2024.2.19
    ARC098DDonation题意:一张无向连通图,\(n\)个点\(m\)条边。你一开始选择任意一个点开始走,到达点\(u\)时,要求你必须有\(a_u\)元,且可以在点\(u\)捐赠\(b_u\)元。可以以任意一点结束,求在所有点捐赠一次的前提下,你的最小初始钱数。\(1\len\len,m\le10^5\)考虑倒着来,......
  • 模拟赛 2024.2.16 解题报告
    A.楼房搭建题意:有\(n\)个数\(a_{1...n}\),以及初始全是\(0\)的\(b_{1...n}\)。现在每次选择一个\(i\in[1,n-1]\),然后选择下面一个操作:\(a_i\getsa_i+1,\spacea_{i+1}\getsa_{i+1}+2\)\(a_i\getsa_i+2,\spacea_{i+1}\getsa_{i+1}+1\)求使得\(\foralli,b......