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 ...
随机推荐
- Pytorch 1.0升级到Pytorch 1.1.0
Pytorch 1.0Pytorch 1.0于2018-12-8发布,详见https://github.com/pytorch/pytorch/releases/tag/v1.0.0 主要更新JIT全 ...
- 利用python爬取王者荣耀英雄皮肤图片
前两天看到同学用python爬下来LOL的皮肤图片,感觉挺有趣的,我也想试试,于是决定来爬一爬王者荣耀的英雄和皮肤图片. 首先,我们找到王者的官网http://pvp.qq.com/web201605 ...
- css 边框上如何写入文字?
方法一: 1.首先,打开html编辑器,新建html文件,例如:index.html. 2.在index.html中的<body>标签中,输入html代码:. <div style= ...
- ABAP Netweaver体内的那些寄生式编程语言
今天这篇文章的主题是:寄生. Jerry最近看到朋友圈里一位朋友分享的一张寄居蟹的照片,对于Jerry这种在内地长大的又很宅的人来说,没有机会看到寄居蟹,所以觉得很新鲜: 寄居蟹主要以螺壳为寄体,寄居 ...
- Mac命令行指定特定程序打开文件
如果文件已被指定默认程序 open httpd.conf 指定一个特定程序打开文件 # 用 sublime text 打开 httpd.conf open -a /Applications/Subli ...
- 这个在Github有52100颗星星的项目,怎么还有人不知道鸭!
Ta是近两年Docker最为火热的开源项目之一.Docker 开启了容器时代,而Ta则革新了我们对于云计算,软件开发流程,业务平台等等方面的认知. Ta就是Kubernetes,/k(j)uːbəˈn ...
- openwrt 切换overlay文件系统为根文件系统
http://blog.chinaunix.net/uid-27057175-id-4584360 openwrt的overlayfs 通过/etc/preinit调用 /sbin/mount_roo ...
- 【OF框架】在Visual Studio中发布Docker镜像,推送镜像到Azure容器注册表
准备 拥有Azure账号,已经创建 Azure容器注册表,获得注册表地址.账号.密码 本地已经在Visual Studio登录Azure账号. 本地已经拥有Docker环境 注意:首次发布Docker ...
- Java泛型全解析【接口、类、封装类型】
目录 1.导读 2.为何需要泛型? 3.泛型的定义格式 3.泛型的好处 4.什么时候使用泛型? 5.泛型的擦除 6.泛型的补偿 7.泛型的应用 7.1[泛型类] ...
- AJAX学习笔记——同源策略
同源策略 同源策略,所有浏览器都实行这个政策 最初,它的含义是指,A 网页设置的 Cookie,B 网页不能打开,除非这两个网页"同源".所谓"同源"指的是&q ...