CSPS分数取mod赛92-93
我好菜啊。。。。。
92只会打暴力,93暴力都不会了
模拟92,
T1:直接ex_gcd加分类讨论即可
T2:考场只会打暴搜,正解为排序后线段树解决,排序的关键字为a+b,因为如果ai<bj&&bi<aj那么i应该在j前。
#include<bits/stdc++.h>
#define N 100050
#define LL long long
using namespace std;
int n,pd[N],cnt,lsh[N<<],ls;
long long dp[N],ans;
struct node{
int a,b,w;
friend bool operator <(const node &x,const node &y)
{
return x.a+x.b<y.a+y.b;
}
}q[N];
inline void init()
{
for(int i=;i<=n;++i)lsh[++ls]=q[i].a,lsh[++ls]=q[i].b;
sort(lsh+,lsh+ls+);ls=unique(lsh+,lsh+ls+)-lsh-;
for(int i=;i<=n;++i){
q[i].a=lower_bound(lsh+,lsh+ls+,q[i].a)-lsh;
q[i].b=lower_bound(lsh+,lsh+ls+,q[i].b)-lsh;
}sort(q+,q+n+);
}
LL ma[N<<],tag[N<<];
inline void plu(int g,LL w){ma[g]+=w,tag[g]+=w;}
inline void upd(int g){ma[g]=max(ma[g<<],ma[g<<|]);}
inline void down(int g){plu(g<<,tag[g]),plu(g<<|,tag[g]);tag[g]=;}
void add(int g,int l,int r,int x,int y,int w)
{
if(l>y||r<x)return;if(l>=x&&r<=y)return plu(g,w);
if(tag[g])down(g);const int m=l+r>>;
add(g<<,l,m,x,y,w);add(g<<|,m+,r,x,y,w);
upd(g);
}
void change(int g,int l,int r,int pos,LL w)
{
if(l==r)return (void)(ma[g]=max(ma[g],w));
if(tag[g])down(g);const int m=l+r>>;
if(pos<=m)change(g<<,l,m,pos,w);
else change(g<<|,m+,r,pos,w);
upd(g);
}
LL ask(int g,int l,int r,int x,int y)
{
if(l>y||r<x)return ;
if(l>=x&&r<=y)return ma[g];
if(tag[g])down(g);
const int m=l+r>>;
const LL a1=ask(g<<,l,m,x,y),a2=ask(g<<|,m+,r,x,y);
return max(a1,a2);
}
inline void duizhangkuaipao()
{
for(int i=;i<=n;++i)
{
dp[i]=ask(,,ls,,min(q[i].a,q[i].b))+q[i].w;
add(,,ls,q[i].a,q[i].b,q[i].w);
change(,,ls,q[i].a,dp[i]);
}
ans=ma[];
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;++i)
scanf("%d%d%d",&q[i].a,&q[i].b,&q[i].w);
init();
duizhangkuaipao();
cout<<ans<<endl;
}
T3:多源点最短路,对于每个点维护到这个点的最短距离和对应的特殊点是那个,在扫描每条边时更新答案即可
#include<bits/stdc++.h>
#define N 200050
#define LL long long
using namespace std;
int n,m,p,a[N],pd[N],bl[N];
const LL inf=;
LL dis[N],ans[N];
int he[N],ne[N<<],to[N<<],w[N<<],tot;
inline void work1()
{
for(int i=,x,y,z;i<=m;++i){
scanf("%d%d%d",&x,&y,&z);
ans[x]=min(ans[x],(LL)z);
ans[y]=min(ans[y],(LL)z);
}
for(int i=;i<=p;++i)printf("%lld ",ans[a[i]]);
}
inline void addedge(int x,int y,int z)
{
to[++tot]=y;ne[tot]=he[x];
w[tot]=z;he[x]=tot;
}
priority_queue<pair<LL,int> >q;
#define mmp make_pair
#define fir first
#define sec second
inline void getans()
{
for(int i=;i<=n;++i)dis[i]=inf;
for(int i=;i<=p;++i)
dis[a[i]]=,bl[a[i]]=a[i],q.push(mmp(,a[i]));
LL d;int g;
while(q.size())
{
g=q.top().sec;
d=-q.top().fir;
q.pop();
if(dis[g]!=d)continue;
// printf("g:%d d:%lld\n",g,d);
for(int i=he[g];i;i=ne[i]){
if(bl[g]&&bl[to[i]]&&bl[to[i]]!=bl[g]){
// printf("g:%d to:%d blg:%d blt:%d new:%lld\n",g,to[i],bl[g],bl[to[i]],d+w[i]+dis[to[i]]);
ans[bl[g]]=min(ans[bl[g]],d+w[i]+dis[to[i]]);
ans[bl[to[i]]]=min(ans[bl[to[i]]],d+w[i]+dis[to[i]]);
}
if(dis[to[i]]>d+w[i]){
dis[to[i]]=d+w[i];bl[to[i]]=bl[g];
q.push(mmp(-dis[to[i]],to[i]));
}
}
}
}
inline void work2()
{ }
int main()
{
// freopen("distance.in","r",stdin);
// freopen("my.out","w",stdout);
scanf("%d%d%d",&n,&m,&p);
for(int i=;i<=p;++i)scanf("%d",&a[i]),ans[a[i]]=inf,pd[a[i]]=;
if(p==n){work1();return ;}
for(int i=,x,y,z;i<=m;++i)
{
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,z);addedge(y,x,z);
}
getans();
for(int i=;i<=p;++i)
printf("%lld ",ans[a[i]]);
}
模拟92,
T1:一眼二分,测大样例发现答案不连续,化一下式子发现是个三维偏序,打个cdq上去A掉。
正解为按a的前缀和排序,把b离散化,在树状数组中插入原数组下标,复杂度为nlogn
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 500050
#define LL long long
using namespace std;
int n,ans=;
LL sb[N],lsh[N<<];
int a[N],b[N],c[N],ls;
inline int read(){
int s=,b=;char c=getchar();
while(c>''||c<''){if(c=='-')b=;c=getchar();}
while(c>=''&&c<='')s=s*+c-'',c=getchar();
if(b)return -s;
return s;
}
struct node{LL a;int b,id;}q[N],qq[N];
inline void init()
{
sort(lsh+,lsh+ls+);
ls=unique(lsh+,lsh+ls+)-lsh-;
for(int i=;i<=n;++i)
q[i].b=lower_bound(lsh+,lsh+ls+,sb[i])-lsh;
}
inline void add(int x,const int v){
while(x<=ls){
if(c[x]>v)c[x]=v;
x+=x&-x;
}
}
inline void del(int x){while(x<=ls){c[x]=n+;x+=x&-x;}}
inline int ask(int x)
{
int ret=n+;
while(x)
{
if(c[x]<ret)ret=c[x];
x-=x&-x;
}
return ret;
}
inline void CDQ(int l,int r)
{
if(l==r)return;
const int m=l+r>>;
CDQ(l,m);CDQ(m+,r);
register int i=l,j=m+,t,o=l;
while(j<=r)
{
while(i<=m&&q[j].a>=q[i].a){
add(q[i].b,q[i].id);
qq[o++]=q[i++];
}
t=q[j].id-ask(q[j].b);
if(t>ans)ans=t;
qq[o++]=q[j++];
}
for(int k=l;k<i;++k)del(q[k].b);
while(i<=m)qq[o++]=q[i++];
for(int i=l;i<=r;++i)q[i]=qq[i];
}
int main()
{
scanf("%d",&n);
lsh[++ls]=;
for(int i=,x;i<=n;++i)q[i].a=q[i-].a+read(),q[i].id=i;
for(int i=,x;i<=n;++i)lsh[++ls]=sb[i]=sb[i-]+read(),c[i]=n+;
c[]=n+;
init();
for(int i=n;i<=ls;++i)c[i]=n+;
CDQ(,n);
printf("%d\n",ans);
}
T2:暴力做法为区间dp,dp[i][j]表示区间[i,j]的答案,for枚举长度,for枚举区间左端点,for枚举根节点复杂度为O(n3)
利用决策单调性优化。发现在一个已有区间的右面插入一个点,原树的根不会左移。同理在右面插入,决策点不会右移。
dp的同时记录决策点即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 5050
#define LL long long
using namespace std;
int n,rt=,po[N][N];
const LL inf=1ll<<;
LL sum[N];
LL ans,dp[N][N];
int main()
{
scanf("%d",&n);
for(int i=,x;i<=n;++i)scanf("%d",&x),sum[i]=sum[i-]+x;
for(int i=;i<=n;++i)dp[i][i]=sum[i]-sum[i-],po[i][i]=i;
for(int len=;len<=n;++len){
for(int i=,j;i+len-<=n;++i){
j=i+len-;dp[i][j]=inf;
for(int k=po[i][j-];k<=po[i+][j];++k)
if(dp[i][k-]+dp[k+][j]<=dp[i][j]){dp[i][j]=dp[i][k-]+dp[k+][j],po[i][j]=k;}
dp[i][j]+=sum[j]-sum[i-];
}
}
printf("%lld\n",dp[][n]);
}
T3:高斯消元,期望题一般逆推。题解:
我们首先考虑单个的 k。设 fi 表示从 i 出发第一次到 k 的期望步数,那么
f k =0,f i =sigma(f j )/x i +1 (i!=k,j 为 i 的所有出边,x i 为 i 的出度),用高斯消元解出 f1 即可。
分治消元的具体做法是:先用前一半的方程进行消元,然后递归后一半;
(恢复原矩阵后)再用后一半的方程进行消元,然后递归前一半。这样当区间缩小到
单点时,这个方程并没有拿来消其它的方程,我们可以直接修改它并求出所有f i 。
类似思想可以参考我这篇题解:https://www.cnblogs.com/loadingkkk/p/11272338.html
#include<cstdio>
#include<iostream>
#define N 320
#define LL long long
using namespace std;
const int mod=;
int n,m,inv[];
LL a[N][N],c[][N][N],b[N],dd[][N],ans[N];
inline int qpow(int d,int z)
{
int ret=;
for(;z;z>>=,d=1ll*d*d%mod)
if(z&)ret=1ll*ret*d%mod;
return ret;
}
inline void init(int n){for(int i=;i<=n;++i)inv[i]=qpow(i,mod-);}
int he[N],ne[],to[],d[N],tot;
inline void addedge(int x,int y)
{
to[++tot]=y;++d[x];
ne[tot]=he[x];he[x]=tot;
}
inline void Gauss(int l,int r,int x,int y)
{
for(int i=l;i<=r;++i)
{
const LL iv=qpow(a[i][i],mod-);
for(int j=;j<=n;++j)
{
if(j==i||!a[j][i])continue;
const LL pl=iv*a[j][i]%mod;
for(int o=x;o<=y;++o){
a[j][o]-=a[i][o]*pl%mod;
if(a[j][o]<)a[j][o]+=mod;
}
b[j]-=b[i]*pl%mod;
if(b[j]<)b[j]+=mod;
}
}
}
inline void solve(int dep,int l,int r)
{
if(l==r){ans[l]=b[]*qpow(a[][],mod-)%mod;return;}
for(int i=;i<=n;dd[dep][i]=b[i],++i)
for(int j=;j<=n;++j)
c[dep][i][j]=a[i][j];
const int m=l+r>>;
Gauss(l,m,l,r);solve(dep+,m+,r);
for(int i=;i<=n;b[i]=dd[dep][i],++i)
for(int j=;j<=n;++j)
a[i][j]=c[dep][i][j];
Gauss(m+,r,l,r);solve(dep+,l,m);
}
inline void work()
{
for(register int i=;i<=n;++i){
a[i][i]=b[i]=mod-;
for(register int j=he[i];j;j=ne[j])
(a[i][to[j]]+=inv[d[i]])%=mod;
}
solve(,,n);
}
int main()
{
// freopen("walk.in","r",stdin);
scanf("%d%d",&n,&m);init(m);
for(int i=,x,y;i<=m;++i){
scanf("%d%d",&x,&y);
addedge(x,y);
}
work();
for(int i=;i<=n;++i)printf("%lld\n",ans[i]);
}
希望下一次能考好吧
CSPS分数取mod赛92-93的更多相关文章
- 组合数取mod
组合数取mod 条件mod是质数,inv 是逆元,fac是阶层: 用于n在10^5左右 maxn=100505: ll fact[maxn],inv[maxn]; ll Pow(ll x,ll n){ ...
- 东北育才 DAY2组合数取mod (comb)
组合数取模(comb) [问题描述] 计算C(m,n)mod 9901的值 [输入格式] 从文件comb.in中输入数据. 输入的第一行包含两个整数,m和n [输出格式] 输出到文件comb.out中 ...
- 牛客小白月赛9 A签到(分数取模,逆元)
传送门 对分母求一下逆元,把除法取模变成乘法取模,逆元介绍看这里 这种方法只适合模为质数的情况 #include<bits/stdc++.h> using namespace std; ; ...
- LeetCode No.91,92,93
No.91 NumDecodings 解码方法 题目 一条包含字母 A-Z 的消息通过以下方式进行了编码: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 给定一个只 ...
- NOIP模拟92&93(多校26&27)
前言 由于太菜了,多校26 只改出来了 T1 ,于是直接并在一起写啦~~~. T0 NOIP 2018 解题思路 第一次考场上面写三分,然而我并不知道三分无法处理不是严格单峰的情况,但凡有一个平台都不 ...
- 淘淘蓝蓝的CSP-S神妙膜你赛2-淘淘蓝蓝喜欢01串 题解
问题简述 给定\(n\)个盒子,每个盒子的容器为\(b[i]\),里面装有\(a[i]\)个物品.今有\(q\)组询问,每组询问给出一个正整数\(k(k<=n)\),已知一个盒子里的一件物品转移 ...
- 「模拟8.21」山洞(矩阵优化DP)
暴力: 正解: 考虑循环矩阵,f[i][j]表示从i点到j点的方案数 我们发现n很小,我们预处理出n次的f[i][j] 然后在矩阵快速幂中,我们要从当前的f[i][j]*f[j][k]-->fi ...
- Noip模拟47 2021.8.25
期望得分:55+24+53 实际得分:0+0+3 乐死 累加变量清零了吗? 打出更高的部分分暴力删了吗? 样例解释换行你看见了吗? T1 Prime 打出55分做法没删原来的暴力,结果就轻松挂55分 ...
- thinkphp中 volist循环的 mod取值的问题
<ul> <volist name="data" id="arr" key="k" mod="2"&g ...
随机推荐
- (转)FFmpeg架构之I/O模块分析
注意:这篇转载的文章比较早,写得很清晰,但是新版的ffmpeg的很多数据结构的名字已经改了.因此只能作参考.(例如ByteIOContext已经改名为AVIOContext) 1概述 ffmpeg项目 ...
- 用 Scoop 管理你的 Windows 软件
包管理系统,Homebrew 就是 macOS 上体验最佳的软件包管理,能帮助我们方便快捷.干净利落的管理软件.在Windows平台上也有一个非常棒的包管理软件--Scoop.Scoop 最适合安装那 ...
- 关于utf8mb4的使用
针对mysql数据库存储一些特殊字符或者emoji的字符,所需要的编码类型.实际上基于efcore框架的情况下,codefirst自动迁移生成的数据库的默认编码格式,就是utf8mb4,以前的时候记得 ...
- JVM性能优化--类加载器,手动实现类的热加载
一.类加载的机制的层次结构 每个编写的".java"拓展名类文件都存储着需要执行的程序逻辑,这些".java"文件经过Java编译器编译成拓展名为". ...
- Go context 介绍和使用
context 上下文管理 context 翻译过来就是上下文管理,主要作用有两个: 控制 goroutine 的超时 保存上下文数据 WithTimeout 通过下面的一个简单的 http 例子进行 ...
- git push error. ! [rejected] master -> master (non-fast-forward)
错误提示: Cheetah@xxxx MINGW64 /e/Projs/enft/data/cv_key_frame (master) $ git push To github.com:Anthony ...
- rem em min-width: 30em 的意思
30em=30rem=30x16px=480px @media only screen and (min-width:30 em){ }
- mysql表设计注意点
[原创]面试官:讲讲mysql表设计要注意啥 需要设计一个主键 因为你不设主键的情况下,innodb也会帮你生成一个隐藏列,作为自增主键.所以啦,反正都要生成一个主键,那你还不如自己指定一个主键,在有 ...
- python 3.6 + robotFramework自动化框架 环境搭建、学习笔记
################################################################# #author: 陈月白 #_blogs: http://www.c ...
- 【HCIA Gauss】学习汇总-数据库管理(数据库设计 范式 索引 分区)-7
zsql user/pasword@ip:port -c "show databases" # 展示一条sql语句 spool file_path 指定输出文件 可以为相对路径 s ...