【XVIII Open Cup E.V. Pankratiev. Grand Prix of Gomel E】Exit Song 题解

题目大意

  电影院观众席为 n × m n \times m n×m 的方阵,其中 k k k 个座位 ( r 1 , s 1 ) , ⋯   , ( r k , s k ) (r_1,s_1),\cdots,(r_k,s_k) (r1,s1),,(rk,sk) 已经被占。问从剩下的座位中,选择某一行的一个连续段(长度至少为 1 1 1)的方案数。

   n , m ≤ 1 0 5 ,    1 ≤ k ≤ n m n,m \leq 10^5,\ \ 1 \le k \le nm n,m105,  1knm,给定 r 1 , s 1 , a r , b r , a s , b s r_1,s_1,a_r,b_r,a_s,b_s r1,s1,ar,br,as,bs,按如下方式生成剩余数据:
r i = ( r i − 1 ⋅ a r + b r )   m o d   n s i = ( s i − 1 ⋅ a s + b s )   m o d   m r_i = (r_{i-1} \cdot a_r + b_r) \bmod n \\ s_i = (s_{i-1} \cdot a_s + b_s) \bmod m ri=(ri1ar+br)modnsi=(si1as+bs)modm

  2s

\\
\\
\\

题解

  它说它是数据随机生成,它可不是随机生成的啊,一次函数,模 n n n,后来它说 k k k O ( n m ) O(nm) O(nm) 的,看来是 有 循 环 节

  这个 r r r s s s 显然是有循环节的。为了方便处理,先把还没进入循环节的坐标( ( r i , s i ) (r_i,s_i) (ri,si) 横纵坐标任意一个没有进入循环节就算这个坐标没有进入循环节)特殊标记出来(怎么用后面再说)。假设去掉这些坐标以后,起始坐标为 ( r 0 , s 0 ) (r_0,s_0) (r0,s0) r r r 序列的循环节长度为 p r pr pr,循环节为 r 0 , ⋯   , r p r − 1 r_0,\cdots,r_{pr-1} r0,,rpr1 s s s 序列的循环节长度为 p s ps ps,循环节为 s 0 , ⋯   , s p s − 1 s_0,\cdots,s_{ps-1} s0,,sps1
  这里会有 p r ≤ n ,   p s ≤ m pr \le n,\ ps \le m prn, psm

  对于 r 0 r_0 r0,暴力把这一行的所有纵坐标求出来(即 s 0 , s p r   m o d   p s , s 2 p r   m o d   p s , ⋯ s_0,s_{pr \bmod ps},s_{2pr \bmod ps},\cdots s0,sprmodps,s2prmodps,,直到超出 k k k 的限制),这个时间是 O ( p s gcd ⁡ ( p r , p s ) ) O(\frac{ps}{\gcd(pr,ps)}) O(gcd(pr,ps)ps) 的。求出来之后丢进一个 set 里,就可以维护出这一行的答案了(记得考虑没进循环节的特殊点)。
  接下来最最重要的就是,发现有些行跟它是相似的!
  考虑第 r p s   m o d   p r r_{ps \bmod pr} rpsmodpr 行,发现它的纵坐标序列跟 r 0 r_0 r0 的纵坐标序列大体相同,只有头尾有些不同。(因为纵坐标的循环节就是 p s ps ps,所以中间大部分纵坐标循环了一圈没有变化,不同的在于, r 0 r0 r0 的最后几个纵坐标放到 r p s   m o d   p r r_{ps \bmod pr} rpsmodpr 里去可能超出了 k k k 的限制, r p s   m o d   p r r_{ps\bmod pr} rpsmodpr 可能在开头会比 r 0 r_0 r0 多几个。)
  而头尾这些不同的元素数量是 O ( ⌈ p s p r ⌉ ) O(\lceil \frac{ps}{pr} \rceil) O(prps) 的,可以用 O ( ⌈ p s p r ⌉ ) O(\lceil \frac{ps}{pr} \rceil) O(prps) 的时间把 set 调整过来。
  同理,第 r 2 p s   m o d   p r r_{2ps \bmod pr} r2psmodpr 行跟第 r p s   m o d   p r r_{ps \bmod pr} rpsmodpr 行也是这样相似的,第 r 3 p s   m o d   p r r_{3ps \bmod pr} r3psmodpr 跟第 r 2 p s   m o d   p r r_{2ps \bmod pr} r2psmodpr 行也是这样相似的……
  因此 r 0 , ⋯   , r p r − 1 r_0,\cdots,r_{pr-1} r0,,rpr1 共分成了 gcd ⁡ ( p s , p r ) \gcd(ps,pr) gcd(ps,pr) 个相似类,每个相似类的大小为 p r gcd ⁡ ( p s , p r ) \frac{pr}{\gcd(ps,pr)} gcd(ps,pr)pr。每个相似类首先暴力求出初始一行的纵坐标序列,丢进 set 里,然后遍历这个相似类,调整 set 算答案。
  暴力求初始纵坐标的时间复杂度为 O ( gcd ⁡ ( p s , p r ) ⋅ p s gcd ⁡ ( p s , p r ) ) = O ( p s ) O(\gcd(ps,pr) \cdot \frac{ps}{\gcd(ps,pr)}) = O(ps) O(gcd(ps,pr)gcd(ps,pr)ps)=O(ps),set 调整的次数为 O ( p r ⋅ ⌈ p s p r ⌉ ) = O ( p s ) O(pr \cdot \lceil \frac{ps}{pr} \rceil) = O(ps) O(prprps)=O(ps),再加上 set 那么这题的复杂度就是 O ( m log ⁡ m ) O(m \log m) O(mlogm)

代码

#include<bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;

typedef long long LL;

const int maxn=1e5+5;

int n,m,r0,s0,ar,br,as,bs;
LL k;

int visr[maxn],viss[maxn],r[maxn],s[maxn],pr,ps;
vector<int> spc[maxn];
void make_period()
{
	while (k && (!visr[r0] || !viss[s0]))
	{
		spc[r0].push_back(s0);
		visr[r0]=1, viss[s0]=1;
		r0=(r0*(LL)ar+br)%n;
		s0=(s0*(LL)as+bs)%m;
		k--;
	}
	
	memset(visr,0,sizeof(visr));
	for(; !visr[r0]; r0=(r0*(LL)ar+br)%n) visr[r0]=1, r[pr++]=r0;
	memset(viss,0,sizeof(viss));
	for(; !viss[s0]; s0=(s0*(LL)as+bs)%m) viss[s0]=1, s[ps++]=s0;
}

inline LL sum1(LL x) {return (x*(x+1))>>1;}

LL ans1,ans;
set<int> S;
void add(int x)
{
	int l,r;
	set<int>::iterator it=S.upper_bound(x);
	r=*it;
	it--;
	l=*it;
	ans1+=sum1(x-l-1)+sum1(r-x-1)-sum1(r-l-1);
	S.insert(x);
}
void del(int x)
{
	int l,r;
	set<int>::iterator it=S.lower_bound(x);
	it--;
	l=*it;
	it++;it++;
	r=*it;
	it--;
	ans1+=sum1(r-l-1)-sum1(x-l-1)-sum1(r-x-1);
	S.erase(it);
}
void calc_ans(int i)
{
	for(int x:spc[i]) add(x);
	ans+=ans1;
	for(int x:spc[i]) del(x);
}

int main()
{
	scanf("%d %d %lld",&n,&m,&k);
	scanf("%d %d %d",&r0,&ar,&br);
	scanf("%d %d %d",&s0,&as,&bs);
	
	make_period();
	
	memset(visr,0,sizeof(visr));
	memset(viss,0,sizeof(viss));
	int timeStamp=0;
	fo(i,0,pr-1) if (!visr[r[i]])
	{
		timeStamp++;
		ans1=sum1(m);
		S.clear();
		S.insert(-1), S.insert(m);
		deque<int> Q;
		LL curTime=i+1;
		for(int j=i%ps; curTime<=k; (j+=pr)%=ps, curTime+=pr)
		{
			if (viss[j]==timeStamp) break;
			Q.push_back(j);
			viss[j]=timeStamp;
			add(s[j]);
		}
		
		for(int ii=i; !visr[r[ii]]; (ii+=ps)%=pr)
		{
			visr[r[ii]]=1;
			if (Q.empty())
			{
				curTime=ii+1;
				for(int j=ii%ps; curTime<=k; (j+=pr)%=ps, curTime+=pr)
				{
					Q.push_back(j);
					add(s[j]);
				}
			} else
			{
				while (Q.front()!=ii%ps)
				{
					int j=((Q.front()-pr)%ps+ps)%ps;
					add(s[j]);
					Q.push_front(j);
				}
			}
			while (!Q.empty() && ii+1+(Q.size()-1)*(LL)pr>k)
			{
				del(s[Q.back()]);
				Q.pop_back();
			}
			calc_ans(r[ii]);
		}
	}
	ans1=sum1(m);
	S.clear();
	S.insert(-1), S.insert(m);
	fo(i,0,n-1) if (!visr[i]) calc_ans(i);
	
	printf("%lld\n",ans);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
An Introduction to Computer Programming Using Interactive Data Language(IDL) Kenneth P.Bowman Department of Atmospheric Sciences Texas A&M University 2004 January 31 Contents Preface ii I IDL BASICS 1 1 Introduction 2 1.1 What is IDL?...........................................2 1.2 IDL resources...........................................4 1.3 The IDL software system.....................................5 2 IDL Manuals and Books 9 2.1 Features of this book.......................................9 2.1.1 Example programs and data...............................9 2.1.2 Figures and illustrations.................................10 2.2 IDL documentation from Research Systems...........................11 2.3 Other IDL books.........................................12 Interactive IDL 14 3.1 IDL commands..........................................14 3.2 Before starting IDL........................................15 3.2.1 Operating system search path..............................16 3.2.2 The startup.pro file...................................16 3.3 Starting and exiting IDL.....................................20 3.4 Interrupting and restarting IDL calculations..........................21 3.5 Simple IDL statements......................................22 3.6 Getting information........................................25 3.7 Variables..............................................26 3.8 Arrays...............................................28 3.9 Graphics..............................................32 3.10 Summary.............................................35 3.11 Exercises..............................................37 IDL Scripts 39 4.1 IDL commands and notation...................................39ONTENTS vii 4.2 A note on files and file names..................................39 4.3 Making a script..........................................40 4.4 Journaling.............................................44 4.5 Summary.............................................46 4.6 Exercises..........

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值