又不知道在干啥了。在联考里忘交了,所以排名是假的。
看一眼$T1$就直接知道怎么做,但是要列一大堆一大堆的式子,所以想放在最后写。
$T2$比较水,不怎么用想,一小时做完。
然后$T3$是个仙人掌的板子题,由于仙人掌专题一直在被咕咕咕所以我一个仙人掌的题都没写过。
然后考场当场$yy$仙人掌的板子,$3.5h$最后也只是拿到了树和仙人球的部分分。
事实证明其实板子我已经完全$yy$出来了,只不过有一个细节出了锅。。。。
再也不想干考场$yy$板子这种事了。。。。拿三四个小时干别人一小时不到的活然后还容易炸心态
平时再也不要留坑了遇到啥学啥肯定是没问题的
T1:island
大意:有一个四联通快共$n$行,每行上是一段连续的区间$[l_i,r_i]$。求所有点对距离和。$n \le 10^6,10^9 \le l_i \le -1 ,1 \le r_i \le 10^9$
讨论一下有哪些路径以及怎么计算贡献:
所有路径的纵坐标差。直接对于每一行维护 上方所有点到当前行的距离,上方点个数。下方同理。扫一遍递推下来就可以。
跨过中线的横坐标差。对于每一行的左侧点考虑走到所有的右侧点右侧到左侧同理。大概是$\frac{r(r+1)}{2} cnt_{left}$
不过中线的横坐标差。暴力枚举两行算贡献的话,发现答案与区间$min$有关。两种情况:(只考虑$i$走到$j$之前的横坐标变化)
首先为了走到$j$行的高于$min$的部分,所有点都要走到恰好$min$的位置$r_j-min$次,每一次的代价就是等差数列求和。
走到低于$min$的部分,那么高于$min$的第$i$行部分要先走到$min$位置,等差数列求和。低于$min$的直接走,二次等差数列求和。
每一部分都很好算。做单调栈维护出最小值控制区间,再用等差数列求和公式优化每一部分就行了。$O(n)$
公式要短一点不然常数硬核破百。及时合并同类项。
1 #include<cstdio> 2 #define ll long long 3 const int S=1000005,mod=998244353; 4 int min(int a,int b){return a<b?a:b;} 5 int mo(int x){return x>=mod?x-mod:x;} 6 void add(int&a,int b){a+=b;a-=a>=mod?mod:0;} 7 void dec(int&a,int b){a-=b;a+=a<0?mod:0;} 8 int d2(int a){return a*499122177ll%mod;} 9 int l[S],r[S],len[S],n,ans; 10 int cal2(int x){return (x+1ll)*x/2%mod;} 11 int cal3(int x){return (x+x+1ll)*(x+1)%mod*x%mod*166374059%mod;} 12 int in(int n,int r){add(ans,cal2(n-1)*1ll*r%mod);add(ans,cal3(n-1)*1ll*r%mod);} 13 void solve(int*a){ 14 static int sta[S],l[S],r[S],top,tot[S],tot2[S]; 15 for(int i=1;i<=n+1;++i){while(a[sta[top]]>a[i])r[sta[top--]]=i-1;sta[++top]=i;} 16 for(int i=n;~i;--i){while(a[sta[top]]>=a[i]&&top)l[sta[top--]]=i+1;sta[++top]=i;} 17 for(int i=1;i<=n;++i)in(a[i],2ll*(i-l[i]+1)*(r[i]-i+1)%mod-1); 18 for(int i=1;i<=n;++i)tot[i]=mo(tot[i-1]+a[i]),tot2[i]=(tot2[i-1]+1ll*a[i]*a[i])%mod; 19 for(int i=1;i<=n;++i) 20 add(ans,2ll*cal2(a[i]-1)*mo(( 21 (tot[i-1]-tot[l[i]-1]-1ll*a[i]*(i-l[i]))%mod*(r[i]-i+1)+ 22 (tot[r[i]]-tot[i]-1ll*a[i]*(r[i]-i))%mod*(i-l[i]+1) 23 )%mod+mod)%mod), 24 add(ans,mo(( 25 (tot2[r[i]]-tot2[i-1]+(tot[r[i]]-tot[i-1])*(1ll-a[i]-a[i])+a[i]*(a[i]-1ll)%mod*(r[i]-i+1))%mod*(tot[i]-tot[l[i]-1])+ 26 (tot2[i]-tot2[l[i]-1]+(tot[i]-tot[l[i]-1])*(1ll-a[i]-a[i])+a[i]*(a[i]-1ll)%mod*(i-l[i]+1))%mod*(tot[r[i]]-tot[i-1]) 27 )%mod+mod)); 28 } 29 int main(){ 30 scanf("%d%*s",&n); 31 for(int i=1;i<=n;++i)scanf("%d%d",&l[i],&r[i]),l[i]=-l[i],len[i]=mo(l[i]+r[i]); 32 int up=0,dw=0,upv=0,dwv=0; 33 for(int i=1;i<=n;++i)add(dw,len[i]),add(dwv,1ll*len[i]*i%mod); 34 for(int i=1;i<=n;++i)dec(dwv,dw),dec(dw,len[i]),add(ans,1ll*len[i]*mo(upv+dwv)%mod),add(up,len[i]),add(upv,up); 35 int totL=0,totR=0; 36 for(int i=1;i<=n;++i)add(totL,l[i]),add(totR,r[i]); 37 for(int i=1;i<=n;++i)add(ans,2ll*totL*cal2(r[i])%mod),add(ans,2ll*totR*cal2(l[i]-1)%mod); 38 solve(l); solve(r); 39 printf("%d\n",ans); 40 }