A.平均数

看到第K小,又确定跟平衡树/主席树没有关系,可以把问题转化为有K-1个答案比它小再考虑二分。

二分平均值x,之后将原序列统一减去x。这时序列中区间和<0的区间个数就是原序列中平均值小于x的区间个数。

求个前缀和,那么区间和<0转化成$sum_l > sum_r$,归并排序求逆序对即可。复杂度$O(n\ log^2 \ n)$

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int N=1e5+5;
const double eps=1e-8;
int n,K,num;
double a[N],b[N],sum[N],c[N];
void merge(int l,int r)
{
if(l==r)return ;
int mid=l+r>>1;
merge(l,mid);merge(mid+1,r);
int i=l,j=mid+1,k=l;
while(i<=mid&&j<=r)
{
if(sum[i]>sum[j])num+=mid-i+1,c[k]=sum[j],j++;
else c[k]=sum[i],i++;
k++;
}
while(i<=mid)c[k]=sum[i],i++,k++;
while(j<=r)c[k]=sum[j],j++,k++;
for(int i=l;i<=r;i++)sum[i]=c[i];
} bool check(double val)
{
sum[0]=0;num=0;
for(int i=1;i<=n;i++)
a[i]=b[i]-val,sum[i]=sum[i-1]+a[i];
merge(0,n);
return num<K;
} int main()
{
n=read();K=read();
double l=0,r=0;
for(int i=1;i<=n;i++)
b[i]=(double)read();
r=1e9+1.0;
while(r-l>eps)
{
double mid=(l+r)/2.0;
if(check(mid))l=mid;
else r=mid;
}
printf("%.4lf\n",l);
return 0;
}

B.涂色游戏

不会。勉强理解题解之后过掉的。矩阵快速幂一直不能游刃有余地运用到dp优化里,这布星啊。

最裸的矩阵快速幂。

这一行的填色方案只与上一行有关,所以dp。

$dp[i][j]$表示在第i行填了特定j中颜色的方案数。

考虑转移。枚举两行的颜色数再枚举交集即可。

如果上一行有i种下一行有j种交集为k种。

转移条件是$i+j-k<=p\ and\ i+j-k>=q$。

那么就是一个组合数学问题了。

先在上一行的颜色里选出重复部分Cki

再选出这一行交集以外的部分Cj−kp−i

然后的问题就是已知某k种颜色填n个位置,要求每种颜色必须出现。我是dp做的,据说可以容斥。

然后发现每一层的转移系数都相同,那就是简单的矩阵快速幂了。

注意取模。

  ——DeepinC

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int N=105,M=2005;
int n,p,q;
ll m,C[N][N],A[N][N],b[N][N],res[N],tmp[N][N],tp[N];
void b_mult()
{
memset(tmp,0,sizeof(tmp));
for(int i=1;i<=p;i++)
for(int j=1;j<=p;j++)
for(int k=1;k<=p;k++)
(tmp[i][j]+=b[i][k]*b[k][j]%mod)%=mod;
for(int i=1;i<=p;i++)
for(int j=1;j<=p;j++)
b[i][j]=tmp[i][j];
} void res_mult()
{
memset(tp,0,sizeof(tp));
for(int i=1;i<=p;i++)
for(int j=1;j<=p;j++)
(tp[i]+=res[j]*b[j][i]%mod)%=mod;
for(int i=1;i<=p;i++)
res[i]=tp[i];
}
int main()
{
scanf("%d%lld%d%d",&n,&m,&p,&q);
C[0][0]=A[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=p;j++)
A[i][j]=(A[i-1][j-1]+A[i-1][j])*j%mod;
for(int i=1;i<=p;i++)
{
C[i][0]=1;
for(int j=1;j<=i;j++)
(C[i][j]=C[i-1][j-1]+C[i-1][j])%=mod;
}
for(int i=1;i<=p;i++)
for(int j=1;j<=p;j++)
for(int k=0;k<=p;k++)
if(i+j-k<=p&&i+j-k>=q)
(b[i][j]+=C[i][k]*C[p-i][j-k]%mod*A[n][j])%=mod;
for(int i=1;i<=p;i++)
res[i]=A[n][i]*C[p][i]%mod;
m--;
while(m)
{
if(m&1)res_mult();
b_mult();
m>>=1;
}
ll ans=0;
for(int i=1;i<=p;i++)
(ans+=res[i])%=mod;
printf("%lld\n",ans);
return 0;
}

C.序列

先用主席树求第一问。

我们注意到,每次修改后对答案作贡献其实只有范围包括修改点的询问,并且改小了做正贡献,改大了做负贡献。

对于询问建立一棵线段树,下标为询问控制的区间,对每一个结点开一个vector,把所询问的值添加进线段树对应的节点。

将询问按询问值排序,之后按顺序全部更新到线段树中。排序是为了让每个节点的vector内部元素保证有序,确保可以二分查找。

之后对于每次修改,在线段树里查一下改之前该位置的贡献(单点查询,路过每个包含的区间时在它的vector里二分查找),再查一下改之后的,二者做差更新答案,然后在外部数组里更改即可。

复杂度$O(n\ log^2 \ n)$。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int N=1e5+5;
typedef long long ll;
int n,m,Q,a[N];
struct ques
{
int l,r,val;
friend bool operator < (ques x,ques y)
{
return x.val<y.val;
}
}q[N];
int ls[N*40],rs[N*40],size[N*40],type,root[N];
ll ans;
void update(int &k,int l,int r,int old,int val)
{
k=++type;
ls[k]=ls[old];
rs[k]=rs[old];
size[k]=size[old]+1;
if(l==r)return ;
int mid=l+r>>1;
if(val<=mid)update(ls[k],l,mid,ls[old],val);
else update(rs[k],mid+1,r,rs[old],val);
}
int query(int k,int l,int r,int val)
{
if(l==r)return size[k];
int mid=l+r>>1,res=0;
if(val<=mid)return size[rs[k]]+query(ls[k],l,mid,val);
else return query(rs[k],mid+1,r,val);
}
vector<int> w[N<<2];
#define ls(k) (k)<<1
#define rs(k) (k)<<1|1
void add(int k,int l,int r,int L,int R,int val)
{
if(L<=l&&R>=r)
{
w[k].push_back(val);
return ;
}
int mid=l+r>>1;
if(L<=mid)add(ls(k),l,mid,L,R,val);
if(R>mid)add(rs(k),mid+1,r,L,R,val);
}
int ask(int k,int l,int r,int pos,int val)
{
int res=upper_bound(w[k].begin(),w[k].end(),val)-w[k].begin()-1;
if(l==r)return res;
int mid=l+r>>1;
if(pos<=mid)res+=ask(ls(k),l,mid,pos,val);
else res+=ask(rs(k),mid+1,r,pos,val);
return res;
}
int main()
{
n=read();m=read();Q=read();
for(int i=1;i<=n;i++)
a[i]=read(),update(root[i],1,n,root[i-1],a[i]);
for(int i=1;i<=m;i++)
{
q[i].l=read(),q[i].r=read(),q[i].val=read();
int res1=query(root[q[i].r],1,n,q[i].val),res2=query(root[q[i].l-1],1,n,q[i].val);
ans+=res1-res2;
}
sort(q+1,q+m+1);
for(int i=1;i<=m;i++)
add(1,1,n,q[i].l,q[i].r,q[i].val);
printf("%lld\n",ans);
while(Q--)
{
int p=read()^ans,v=read()^ans;
int res1=ask(1,1,n,p,a[p]),res2=ask(1,1,n,p,v);
ans+=res2-res1;
a[p]=v;
printf("%lld\n",ans);
}
return 0;
}

[CSP-S模拟测试52]题解的更多相关文章

  1. csp-s模拟测试52平均数,序列题解

    题面:https://www.cnblogs.com/Juve/articles/11602244.html 平均数: 第k个平均数不好求,我们考虑二分,转化成平均数小于x的有几个 虑把序列中的每个数 ...

  2. CSP-S 模拟测试94题解

    T1 yuuustu: 可以对两边取对数,然后就转化为两个double的比较,时间复杂度$O(n)$ 然后我就用神奇0.4骗分水过 #include<bits/stdc++.h> usin ...

  3. CSP-S模拟测试 88 题解

    T1 queue: 考场写出dp柿子后觉得很斜率优化,然后因为理解错了题觉得斜率优化完全不可做,只打了暴力. 实际上他是可以乱序的,所以直接sort,正确性比较显然,贪心可证,然后就是个sb斜率优化d ...

  4. CSP-S 模拟测试92 题解

    话说我怎么觉得我没咕多长时间啊,怎么就又落了20多场题解啊 T1 array: 根据题意不难列出二元一次方程,于是可以用exgcd求解,然而还有一个限制条件就是$abs(x)+abs(y)$最小,这好 ...

  5. CSP-S 模拟测试57题解

    人生第一次A,B层一块考rank2,虽然说分差没几分,但还是值得纪念. 题解: T1 天空龙: 大神题,因为我从不写快读也没有写考场注释的习惯,所以不会做,全hzoi就kx会做,kx真大神级人物. T ...

  6. CSP-S 模拟测试 51 题解

    考试过程: 惯例先看一遍三道题,T1 一开始反应要求割点,但是这是有向图,肯定不能求割点,康了一下数据范围,有40%是树的,还不错,决定待会在打. 看T2 字符串题,完了我字符串最弱了,肯定只能打暴力 ...

  7. CSP-S 模拟测试 45 题解

    由于咕掉的题解太多了,所以只能趁改完不动题的时间,来补补坑qwq,还是太弱了. 考试过程: 到新机房的第一次考试,貌似海星? 第一题一开始就觉得是个贪心,但以为所有小怪兽都要打完,所以想复杂了,但后来 ...

  8. [CSP-S模拟测试97]题解

    A.小盆友的游戏 感觉题解解释的很牵强啊……还是打表找规律比较靠谱 对于每个人,它构造了一个期望函数$f(x)$,设它的跟班个数为$cnt[x]$,那么令$f(x)=2^{cnt[x]}-1$(??鬼 ...

  9. [CSP-S模拟测试96]题解

    以后不能再借没改完题的理由不写题解了…… A.求和 求$\sum \sum i+j-1$ 柿子就不化了吧……这年头pj都不考这么弱智的公式化简了…… 坑点1:模数不定,可能没有2的逆元,那么只要先把乘 ...

随机推荐

  1. 10.15 sed 命令实践

    在n行前插入 [root@wen data]# sed '2i 106,dandan,CSO' person.txt101,oldboy,CEO106,dandan,CSO102,zhangyao,C ...

  2. element table组件懒加载

    directives : { loadmore : { bind(el, binding) { const selectWrap = el.querySelector('.el-table__body ...

  3. Axure RP 8.0软件安装教程

    Axure8.0(32/64)位下载地址: 链接:https://pan.baidu.com/s/1qYSLkKW 密码:skaw 软件介绍: Axure RP是一个专业的快速原型设计工具,让负责定义 ...

  4. DB-概念-同义词:同义词/Synonym

    ylbtech-DB-概念-同义词:同义词/Synonym 同义词的概念 :英文(synonym)是指向其它数据库表的数据库指针.同义词有私有(private)和公共(public)两种类型. 1.返 ...

  5. pip install 报SSL异常和timeout异常

    在安装pip3 install virtualenv时报了SSL异常 如图 pip is configured with locations that require TLS/SSL, however ...

  6. PS操作

    笔:B 橡皮:E 新建:C+N 选取套索:L 套索后按Alt,移动 放大:Ctrl + “+” 或 Z 缩小:Ctrl + “-” 或 Alt Z / Alt ,然后用滑轮控制大小 撤销:Ctrl + ...

  7. delphi xe2 opencv 学习

    安装环境 delphi xe2 + opencv opencv 从下面的地方下载  https://github.com/Laex/Delphi-OpenCV然后按照 此网站的 说明 一项以项的 安装 ...

  8. TList TObjectList的区别和使用

    所在的单元 TList(Classes.pas) TObjectList(Contnrs.pas) TObjectList对象的创建方法有一个参数: constructor TObjectList.C ...

  9. mongo 慢查询配置

    我是分片部署,所以慢查询相关的配置是在启动片服务上. 执行查询命令,是在share的primary 上. 1. mongodb慢查询   配置 慢查询数据主要存储在 local库的system.pro ...

  10. spring boot 尚桂谷学习笔记11 数据访问03 JPA

    整合JPA SpringData 程序数据交互结构图 (springdata jpa 默认使用 hibernate 进行封装) 使用之后就关注于 SpringData 不用再花多经历关注具体各个交互框 ...