洛谷3月月赛II T2-4简要题解

T2 无论怎样神树大人都会删库跑路

注意暴力双端队列+桶计算时,一轮中可能对某个长为 1 0 5 10^5 105的小串反复插入,会T。

判断字符串相同的条件比较特殊:每个数字出现次数相同则字符串相同。桶可以转成哈希—— b a s e base base进制的每一位系数分别表示这个位数的出现次数。
记录每个小串的整体哈希值,插入删除就是 O ( 1 ) O(1) O(1)的。

首先暴力前几轮(一轮指的是完整的 m m m次操作),使得小串连接总长 ≥ T \geq T T,后面每轮都是等价的,再多进行一轮算一下每次操作的贡献即可。

#include<bits/stdc++.h>
#define pii pair<int,int>
#define mkp make_pair
#define fi first
#define sc second
#define gc getchar
#define pb push_back
using namespace std;
const int N=1e5+10,p1=1e9+7,p2=1e9+9,bs=1e5+7;
typedef long long ll;
typedef double db;

int n,T,q,m,R[N],sz[N],a[N];
int r[N],gx[N],rnd,L,t[N];
pii pw[N],ori,v,nw;ll ans,whl;
vector<pii>hz[N];

char cp;
inline int rd()
{
   
	cp=gc();int x=0,f=1;
	for(;!isdigit(cp);cp=gc()) if(cp=='-') f=-1;
	for(;isdigit(cp);cp=gc()) x=x*10+(cp^48);
	return f*x;
}

inline int ad(int x,int y,int p){
   x+=y;return x>=p?x-p:x;}
inline int dc(int x,int y,int p){
   x-=y;return x<0?x+p:x;}
inline pii operator *(pii a,int b){
   return mkp((ll)a.fi*b%p1,(ll)a.sc*b%p2);}
inline pii operator +(pii a,int b){
   return mkp(ad(a.fi,b,p1),ad(a.sc,b,p2));}
inline pii operator +(pii a,pii b){
   return mkp(ad(a.fi,b.fi,p1),ad(a.sc,b.sc,p2));}
inline pii operator -(pii a,pii b){
   return mkp(dc(a.fi,b.fi,p1),dc(a.sc,b.sc,p2));}
inline pii operator *(pii a,pii b){
   return mkp((ll)a.fi*b.fi%p1,(ll)a.sc*b.sc%p2);}

struct P{
   int id,len;}tp;
deque<P>que;

inline void upd(int x)
{
   
    nw=nw+hz[x][sz[x]];L+=sz[x];
	que.push_back((P){
   x,sz[x]});
    for(;L>T;){
   
		tp=que.front();que.pop_front();nw=nw-hz[tp.id][tp.len];
		if(L-tp.len>=T) L-=tp.len;else{
   
			nw=nw+hz[tp.id][T-L+tp.len];
			que.push_front((P){
   tp.id,T-L+tp.len});L=T;
		}
	}
}

int main(){
   
	int i,j,x,y,mx=0;pw[0]=mkp(1,1);
	for(i=1;i<N;++i) pw[i]=pw[i-1]*bs;
    n=rd();T=rd();q=rd();
	for(i=1;i<=T;++i) ori=ori+pw[rd()+1];
    for(i=1;i<=n;++i){
   
       sz[i]=x=rd();hz[i].resize(x+1);v.fi=v.sc=0;
	   for(j=1;j<=x;++j) {
   a[j]=rd()+1;v=v+pw[a[j]];}
	   for(j=x;j>0;--j) {
   hz[i][j]=v;v=v-pw[a[x-j+1]];}
	}
	for(m=rd(),i=1;i<=m;++i) whl+=sz[(r[i]=rd())];
	rnd=((T-1)/whl+1)*m;
	for(i=1;i<=q && i<=rnd;++i){
   upd(r[(i-1)%m+1]);ans+=(L==T && ori==nw);}
	for(i=1;i<=m && rnd+i<=q;++i){
   upd(r[(i-1)%m+1]);gx[i]=gx[i-1]+(ori==nw);}
	if(q>rnd) ans+=(ll)gx[m]*((q-rnd)/m)+gx[q%m];
    printf("%lld",ans);
	return 0;
}



T3 OwenOwl 不学车也不删库

神仙构造题还是不会做 (*  ̄︿ ̄)

官方题解:

数形结合,不妨将原图看做一维直线上的模 p p p意义下的 p p p个点 ( 0 , 1 , . . . , p − 1 ) (0,1,...,p-1) (0,1,...,p1) p k p^k p

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值