考虑第$i$列的答案,即找到一个区间$[l,r]$,使得:

1.$l$和$r$要同奇偶,令$ans=\frac{r-l}{2}$,要求尽量大($ans+1$即为该列答案)

2.$\forall 0\le j\le ans$,$[l+j,r-j]\subseteq [l_{i-j},r_{i-j}],[l_{i+j},r_{i+j}]$(两个都包含)

两个都包含可以看成求交,那么即$l\ge \max(l_{i-j},l_{i+j})-j$,类似的$r\le \min(r_{i-j},r_{i+j})+j$,很明显$l$和$r$都会取到端点,只需要保证长度足够,即$ans$合法当且仅当
$$
\min_{0\le j\le ans}(\min(r_{i-j},r_{i+j})+j)-\max_{0\le j\le ans}(\max(l_{i-j},l_{i+j})-j)\ge 2ans
$$
由于相邻两列答案至多相差1,记上一列的答案为$ans$,那么只需要判定$ans\pm 1$即可

注意到一次判定也就是求区间$l_{i}/r_{i}\pm i$最小和最大值,用树状数组维护复杂度过高,考虑用单调队列来维护,通过调整判定$ans\pm 1$的顺序每一次询问的右端点单调不下降,左端点至多减小1,复杂度为$o(n)$

时间复杂度为$o(n)$,且常数略大

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 5000005
4 #define mod 998244353
5 #define ull unsigned long long
6 int t,n,ans,sum,mi[N],l[N],r[N];
7 struct pqueue{
8 int p,L,R,x,y,a[N],q[N];
9 void add(int k){
10 while ((x<y)&&(a[k]<=a[q[y-1]]))y--;
11 q[y++]=k;
12 }
13 int query(int l,int r){
14 int ans=0x3f3f3f3f;
15 //q头尾为[x,y],是[L,R]的单调队列,询问[l,r]
16 for(int i=l;i<L;i++)ans=min(ans,a[i]);
17 assert(R<=r);
18 while (R<r)add(++R);
19 if (L<l){
20 L=l;
21 while ((x<y)&&(q[x]<L))x++;
22 }
23 ans=min(ans,a[q[x]]);
24 return p*ans;
25 }
26 }Q[4];
27 ull calc(ull &A,ull &B){
28 ull T=A,S=B;
29 A=S;
30 T^=(T<<23);
31 T^=(T>>17);
32 T^=(S^(S>>26));
33 B=T;
34 return T+S;
35 }
36 void read(){
37 int L,X,Y;
38 ull A,B;
39 scanf("%d%d%d%llu%llu",&L,&X,&Y,&A,&B);
40 for(int i=1;i<=n;i++){
41 l[i]=calc(A,B)%L+X;
42 r[i]=calc(A,B)%L+Y;
43 if (l[i]>r[i])swap(l[i],r[i]);
44 }
45 }
46 void init(){
47 for(int i=0;i<4;i++)Q[i].L=Q[i].R=Q[i].x=Q[i].y=0;
48 for(int i=1;i<=n;i++)Q[0].a[i]=r[i]-i;
49 for(int i=1;i<=n;i++)Q[1].a[i]=r[i]+i;
50 for(int i=1;i<=n;i++)Q[2].a[i]=-(l[i]+i);
51 for(int i=1;i<=n;i++)Q[3].a[i]=-(l[i]-i);
52 }
53 bool check(int i,int ans){
54 if ((i+ans>n)||(i-ans<=0))return 0;
55 int r=min(Q[0].query(i-ans,i)+i,Q[1].query(i,i+ans)-i);
56 int l=max(Q[2].query(i-ans,i)-i,Q[3].query(i,i+ans)+i);
57 return r-l>=2*ans;
58 }
59 int main(){
60 mi[0]=1;
61 for(int i=1;i<N-4;i++)mi[i]=3LL*mi[i-1]%mod;
62 Q[0].p=Q[1].p=1;
63 Q[2].p=Q[3].p=-1;
64 scanf("%d",&t);
65 for(int ii=1;ii<=t;ii++){
66 scanf("%d",&n);
67 read();
68 init();
69 ans=0;
70 sum=1;
71 for(int i=2;i<=n;i++){
72 if (!check(i,ans))ans--;
73 else{
74 if (check(i,ans+1))ans++;
75 }
76 sum=(sum+1LL*mi[i-1]*(ans+1))%mod;
77 }
78 printf("Case #%d: %d\n",ii,sum);
79 }
80 }

最新文章

  1. C#操作mysql数据库
  2. C# 使用网易邮箱发送邮件
  3. CAD2015安装教程 AutoCAD2015中文版安装激活图文教程
  4. 20145224&amp;20145238《信息安全系统设计基础》实验一 开发环境的熟悉
  5. Android--入门
  6. DEDECMS全版本gotopage变量XSS ROOTKIT 0DAY
  7. Missing artifact com.sun:tools:jar 1.5.0 终极解决方法
  8. Threatening letter in Naver Line App
  9. POJ1860 Currency Exchange(最短路)
  10. NOIP2011-普及组复赛模拟试题-第一题-NBA总冠军
  11. 16.如何做到webpack打包vue项目后,可以修改配置文件
  12. HTML、CSS、JS 复习——序
  13. 数据结构-堆 C与C++的实现
  14. Beta阶段总结分析报告
  15. jQuery 写的textarea输入字数限制
  16. shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
  17. python requests post和get
  18. 力扣(LeetCode) 849. 到最近的人的最大距离
  19. spring中ApplicationContextAware接口描述
  20. git 创建标签和删除标签

热门文章

  1. 《手把手教你》系列技巧篇(二十九)-java+ selenium自动化测试- Actions的相关操作上篇(详解教程)
  2. 手机淘宝轻店业务 Serverless 研发模式升级实践
  3. 从零入门 Serverless | SAE 的远程调试和云端联调
  4. 15-ThreadLocalRandom类剖析
  5. 分布式应用开发 | SpringBoot+dubbo+zookeeper实现服务注册发现 | 远程服务调用
  6. hdoj_Problem1.1.8_A+B for Input-Output Practice (VIII)
  7. perl打开读取文件(open)
  8. ArrayList和Vector
  9. shopping cart
  10. javascript高级程序设计第三版书摘