2023NOIP A层联测6 数点

2023-10-11 18:45
文章标签 联测 2023noip 数点

本文主要是介绍2023NOIP A层联测6 数点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目大意

给你一个排列 p p p,对于每一个 i i i,我们在平面上,放置一个点 ( i , p i ) (i,p_i) (i,pi)。对于坐标上下限都在 1 ∼ n 1\sim n 1n内的全体 ( n ( n + 1 ) 2 ) 2 (\frac{n(n+1)}{2})^2 (2n(n+1))2矩形,求每个矩形内部点数的 k k k次方之和。

形式化地,请你计算

∑ 1 ≤ l ≤ r ≤ n ∑ 1 ≤ d ≤ u ≤ n ∣ { i ∣ l ≤ i ≤ r ∨ d ≤ p i ≤ u } ∣ \sum\limits_{1\leq l\leq r\leq n}\sum\limits_{1\leq d\leq u\leq n}|\{i|l\leq i\leq r\vee d\leq p_i\leq u\}| 1lrn1dun{ilirdpiu}

1 ≤ n ≤ 1 0 5 , 1 ≤ k ≤ 3 1\leq n\leq 10^5,1\leq k\leq 3 1n105,1k3


题解

我们可以考虑拆贡献,点数的 k k k次方可以看成选 k k k个点的方案的线性组合。

什么意思呢?就是在这 n n n个点中有序地可重地选择 k k k个点,将所有包含这 k k k个点的矩形的贡献 + 1 +1 +1,注意所有从 n n n个点中有序地可重地选 k k k个点的方案都要被计算贡献。

为什么可以这样呢?对于每个矩形,设这个矩形内的点数为 t t t,在这个矩形中有序地可重地选 k k k个点的方案数为 t k t^k tk,也就是说这个矩形在上面计算贡献的时候将贡献加了 t k t^k tk次一。

下面,我们来求 k k k为不同的值时的答案。

k = 1 k=1 k=1

对每个点 ( x , p x ) (x,p_x) (x,px),答案的贡献增加 x × ( n − x + 1 ) × p x × ( n − p x + 1 ) x\times (n-x+1)\times p_x\times (n-p_x+1) x×(nx+1)×px×(npx+1)

k = 2 k=2 k=2

我们考虑选的两个点相同的情况和两个点不同的情况。

对于两个点相同的情况,这其实就是 k = 1 k=1 k=1的情况,每种情况会被算一次。

对于两个点不同的情况,我们可以分为顺序对和逆序对来考虑:

  • 对于顺序对 x < y , p x < p y x<y,p_x<p_y x<y,px<py,其贡献为 x × p x × ( n − y + 1 ) × ( n − p y + 1 ) x\times p_x\times (n-y+1)\times (n-p_y+1) x×px×(ny+1)×(npy+1),将 x × p x x\times p_x x×px存入树状数组中,再用 ( n − y + 1 ) × ( n − p y + 1 ) (n-y+1)\times (n-p_y+1) (ny+1)×(npy+1)来乘即可
  • 对于逆序对 x < y , p x > p y x<y,p_x>p_y x<y,px>py将排列翻转之后按顺序对的方法来做即可

因为选点是有序的,每种顺序对和逆序对都用两种选法被选到,所以两个点不同的情况的贡献要乘 2 2 2

k = 3 k=3 k=3

k = 1 k=1 k=1的贡献计算一次(三次选择同一个点), k = 2 k=2 k=2的贡献计算两次(三次选择两个不同的点),下面再考虑三次选择三个不同的点的贡献。

分为两种本质不同的情况:

情况1
------
|*   |
| *  |
|  * |
------

这种情况出现了 2 2 2次(按 i i i左右翻转,总共有 2 2 2次),用两个树状数组维护即可。

情况2
------
|  * |
|*   |
| *  |
------

这种情况总共出现了 4 4 4次(按 i i i左右翻转,按 p i p_i pi上下翻转,四个角度各一次,总共有 4 4 4次),用线段树来维护即可。可以在加入第一个点时直接在对应位置上加数,在加入第二个点时将其后缀乘上对应的数,再加入第三个点时查询前缀和。

因为选点是有序的,每种顺序对和逆序对都用六种选法被选到,所以两个点不同的情况的贡献要乘 6 6 6

时间复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn)

code

#include<bits/stdc++.h>
#define lc k<<1
#define rc k<<1|1
using namespace std;
const long long mod=998244353;
int n,K,p[100005];
long long tr1[100005],tr2[100005];
long long s[500005],hv[500005],ly[500005];
int lb(int i){return i&(-i);
}
void pt1(int i,long long v){while(i<=n){tr1[i]=(tr1[i]+v)%mod;i+=lb(i);}
}
long long find1(int i){long long re=0;while(i){re=(re+tr1[i])%mod;i-=lb(i);}return re;
}
void pt2(int i,long long v){while(i<=n){tr2[i]=(tr2[i]+v)%mod;i+=lb(i);}
}
long long find2(int i){long long re=0;while(i){re=(re+tr2[i])%mod;i-=lb(i);}return re;
}
void build(int k,int l,int r){s[k]=hv[k]=ly[k]=0;if(l==r) return;int mid=l+r>>1;build(lc,l,mid);build(rc,mid+1,r);
}
void down(int k){s[lc]=(s[lc]+hv[lc]*ly[k])%mod;s[rc]=(s[rc]+hv[rc]*ly[k])%mod;ly[lc]=(ly[lc]+ly[k])%mod;ly[rc]=(ly[rc]+ly[k])%mod;ly[k]=0;
}
void ch(int k,int l,int r,int x,long long y){if(l==r&&l==x){hv[k]=y;s[k]=ly[k]=0;return;}if(ly[k]) down(k);int mid=l+r>>1;if(x<=mid) ch(lc,l,mid,x,y);else ch(rc,mid+1,r,x,y);hv[k]=(hv[lc]+hv[rc])%mod;s[k]=(s[lc]+s[rc])%mod;
}
void ts(int k,int l,int r,int x,int y,long long v){if(l>=x&&r<=y){ly[k]=(ly[k]+v)%mod;s[k]=(s[k]+v*hv[k])%mod;return;}if(ly[k]) down(k);int mid=l+r>>1;if(x<=mid) ts(lc,l,mid,x,y,v);if(y>mid) ts(rc,mid+1,r,x,y,v);s[k]=(s[lc]+s[rc])%mod;
}
long long find(int k,int l,int r,int x,int y){if(l>=x&&r<=y) return s[k];if(ly[k]) down(k);int mid=l+r>>1;long long re=0;if(x<=mid) re=(re+find(lc,l,mid,x,y))%mod;if(y>mid) re=(re+find(rc,mid+1,r,x,y))%mod;return re;
}
long long gt(){long long re=0;build(1,1,n);for(int i=1;i<=n;i++){re=(re+find(1,1,n,1,p[i])*(n-i+1)%mod*(n-p[i]+1)%mod)%mod;ts(1,1,n,p[i],n,p[i]);ch(1,1,n,p[i],i);}return re;
}
long long gt1(){long long re=0;for(int i=1;i<=n;i++){re=(re+1ll*i*(n-i+1)%mod*p[i]%mod*(n-p[i]+1)%mod)%mod;}return re;
}
long long gt2(){long long re=0;for(int i=1;i<=n;i++){re=(re+find1(p[i])*(n-i+1)%mod*(n-p[i]+1)%mod)%mod;pt1(p[i],1ll*i*p[i]%mod);}for(int i=1;i<=n;i++){tr1[i]=0;if(i<n-i+1) swap(p[i],p[n-i+1]);}for(int i=1;i<=n;i++){re=(re+find1(p[i])*(n-i+1)%mod*(n-p[i]+1)%mod)%mod;pt1(p[i],1ll*i*p[i]%mod);}for(int i=1;i<=n;i++){tr1[i]=0;if(i<n-i+1) swap(p[i],p[n-i+1]);}return re;
}
long long gt3(){long long re=0;for(int i=1;i<=n;i++){long long now=find1(p[i]);pt1(p[i],1ll*i*p[i]%mod);re=(re+find2(p[i])*(n-i+1)%mod*(n-p[i]+1)%mod)%mod;pt2(p[i],now);}for(int i=1;i<=n;i++){tr1[i]=tr2[i]=0;if(i<n-i+1) swap(p[i],p[n-i+1]);}for(int i=1;i<=n;i++){long long now=find1(p[i]);pt1(p[i],1ll*i*p[i]%mod);re=(re+find2(p[i])*(n-i+1)%mod*(n-p[i]+1)%mod)%mod;pt2(p[i],now);}for(int i=1;i<=n;i++){tr1[i]=tr2[i]=0;if(i<n-i+1) swap(p[i],p[n-i+1]);}re=(re+gt())%mod;for(int i=1;i<=n;i++)if(i<n-i+1) swap(p[i],p[n-i+1]);re=(re+gt())%mod;for(int i=1;i<=n;i++)p[i]=n-p[i]+1;re=(re+gt())%mod;for(int i=1;i<=n;i++)if(i<n-i+1) swap(p[i],p[n-i+1]);re=(re+gt())%mod;return re;
}
int main()
{freopen("points.in","r",stdin);freopen("points.out","w",stdout);scanf("%d%d",&n,&K);for(int i=1;i<=n;i++){scanf("%d",&p[i]);}if(K==1) printf("%lld",gt1());else if(K==2)  printf("%lld",(gt1()+2*gt2())%mod);else{printf("%lld",(gt1()+6*gt2()+6*gt3())%mod);}return 0;
}

这篇关于2023NOIP A层联测6 数点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/190088

相关文章

ACM 粗心永远AC不了系列——小Hi的烦恼|“五维数点”问题

问题来源:hiho一下第147周 小Hi的烦恼 题目1 : 小Hi的烦恼 时间限制: 5000ms 单点时限: 1000ms 内存限制: 1024MB 描述 小Hi从小的一大兴趣爱好就是学习,但是他发现尽管他认真学习,依旧有学神考的比他好。 小Hi在高中期间参加了市里的期末考试,一共五门:语文、数学、英语、物理、化学。 成绩出来之后,小Hi发现有些同学,所有科目

C语言练习记录(蓝桥杯练习)(小蓝数点)

目录  小蓝数点  第一题程序的输出结果是?: 第二题下面代码的执行结果是什么?: 第三题下面代码的执行结果是什么?: 第四题关于关系操作符说法错误的是?: 第五题对于下面代码段,y的值为? 第六题sum = 21 第七题设字符型变量x的值是064,表达式“~ x ^ x << 2 & x”的值是()​编辑 第八题变量void (*s[5])(int)表示意思为

NOIP2023模拟16联测37 大眼鸹猫

题目大意 有两个长度为 n n n的序列 a , b a,b a,b,这两个序列都是单调不降的。 你可以对 a a a进行不超过 m m m次操作,每次操作你可以选择一个 i i i满足 1 ≤ i ≤ n 1\leq i\leq n 1≤i≤n,然后选择一个整数(可以是负数) x x x,将 a i a_i ai​加上 x x x,这次操作要花费 x 2 x^2 x2的代价。 在操作的过程

NOIP2023模拟16联测37 总结

NOIP2023模拟16联测37 总结 T 1 T1 T1 求有多少区间的异或和为 k k k 的因子, n , k ≤ 1 0 5 n , k \le 10^5 n,k≤105 。看到异或就想到了前几天的拿到按位考虑的题目,想了半小时没想到。突然想前缀和,对每个 k k k 的因子记录一下 a ⊕ k a \oplus k a⊕k 的数量就好了 。 T 2 T2 T2 每次可以删去

NOIP2023模拟16联测37 D. 小猫吃火龙果

NOIP2023模拟16联测37 D. 小猫吃火龙果 文章目录 NOIP2023模拟16联测37 D. 小猫吃火龙果题目大意思路code 题目大意 有 n n n 个物品 A A A , B B B , C C C , A A A 吃 B B B, B B B 吃 C C C, C C C 吃 A A A,有两种操作,给 [ l , r ] [ l , r ]

2023.11.10联测总结

T 1 T1 T1求的是有多少个区间的异或和是 k k k的因子, n , k ≤ 1 0 5 n,k \leq 10^5 n,k≤105。 这道题用前缀和维护一下,暴力枚举所有区间就有 80 80 80分。 有一瞬间想过枚举因数,但是脑抽以为要 O ( n ) \mathcal O(n) O(n)枚举,然后就跑路了。 T 2 T_2 T2​给出一个有 n n n个数的数列,每次可以删去

2023NOIP A层联测28-大眼鸹猫

给你两个长度为 n n n 的序列 a , b a,b a,b,这两个序列都是单调不降的。 你可以对 a a a 进行不超过 m m m 次操作,每次操作你可以选择一个 i i i 满足 1 ≤ i ≤ n 1\le i\le n 1≤i≤n,然后选择一个整数(可以是负数) x x x,将 a i a_i ai​ 加上 x x x,这一次操作需要花费 x 2 x^2 x2 的代

NOIP2023模拟13联测34 B.competition

NOIP2023模拟13联测34 B.competition 文章目录 NOIP2023模拟13联测34 B.competition题目大意思路code 题目大意 现在有 n n n 个区间 [ l i , r i ] [l_i , r_i] [li​,ri​] ,现在问你选取若干的连续的区间的区间并的大小的和。 思路 设 p r e i , j pre_{i ,

NOIP2023模拟1联测22 爆炸

NOIP2023模拟1联测22 爆炸 题目大意 ​ 自己看 思路 当一个炸弹被引爆后,它的方向是固定的。如果被竖着引爆,那么应该选择横着引爆,否则选择竖着引爆,这是显然 的。 考虑对于每个炸弹 ( i , j ) (i , j) (i,j) 将第 i i i 行和第 j j j 列连边 对于每个水晶 ( i , j ) (i , j) (i,j) 如果 i i i 行和

NOIP2023模拟13联测34 competition

题目大意 有一场题目数量为 m m m的比赛,有一个团队想要来参加。 这个团队有 n n n个选手,编号为 i i i的选手能做第 l i ∼ r i l_i \sim r_i li​∼ri​道题,每题他都有 100 % 100\% 100%的概率做出来。 这个团队会随机派出一只队伍来参加这个比赛。 因为编号相邻的人关系更好,默契度也更高,所以一个团队派出的队伍一直都是编号为连续区间的选手