我好菜啊。。。。。

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的更多相关文章

  1. 组合数取mod

    组合数取mod 条件mod是质数,inv 是逆元,fac是阶层: 用于n在10^5左右 maxn=100505: ll fact[maxn],inv[maxn]; ll Pow(ll x,ll n){ ...

  2. 东北育才 DAY2组合数取mod (comb)

    组合数取模(comb) [问题描述] 计算C(m,n)mod 9901的值 [输入格式] 从文件comb.in中输入数据. 输入的第一行包含两个整数,m和n [输出格式] 输出到文件comb.out中 ...

  3. 牛客小白月赛9 A签到(分数取模,逆元)

    传送门 对分母求一下逆元,把除法取模变成乘法取模,逆元介绍看这里 这种方法只适合模为质数的情况 #include<bits/stdc++.h> using namespace std; ; ...

  4. LeetCode No.91,92,93

    No.91 NumDecodings 解码方法 题目 一条包含字母 A-Z 的消息通过以下方式进行了编码: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 给定一个只 ...

  5. NOIP模拟92&93(多校26&27)

    前言 由于太菜了,多校26 只改出来了 T1 ,于是直接并在一起写啦~~~. T0 NOIP 2018 解题思路 第一次考场上面写三分,然而我并不知道三分无法处理不是严格单峰的情况,但凡有一个平台都不 ...

  6. 淘淘蓝蓝的CSP-S神妙膜你赛2-淘淘蓝蓝喜欢01串 题解

    问题简述 给定\(n\)个盒子,每个盒子的容器为\(b[i]\),里面装有\(a[i]\)个物品.今有\(q\)组询问,每组询问给出一个正整数\(k(k<=n)\),已知一个盒子里的一件物品转移 ...

  7. 「模拟8.21」山洞(矩阵优化DP)

    暴力: 正解: 考虑循环矩阵,f[i][j]表示从i点到j点的方案数 我们发现n很小,我们预处理出n次的f[i][j] 然后在矩阵快速幂中,我们要从当前的f[i][j]*f[j][k]-->fi ...

  8. Noip模拟47 2021.8.25

    期望得分:55+24+53 实际得分:0+0+3 乐死 累加变量清零了吗? 打出更高的部分分暴力删了吗? 样例解释换行你看见了吗? T1 Prime 打出55分做法没删原来的暴力,结果就轻松挂55分 ...

  9. thinkphp中 volist循环的 mod取值的问题

    <ul> <volist name="data" id="arr" key="k" mod="2"&g ...

随机推荐

  1. 静态成员函数和(CPP与C结构体的区别)

    #include <iostream> using namespace std.; //这种写法只是CPP中的struct的用法,但是在C中还是不支持的. //C中的结构体不支持写方法的. ...

  2. spring 条件化配置

    步骤一: 实现接口:org.springframework.context.annotation.Condition import org.springframework.context.annota ...

  3. jquery.marquee

    http://aamirafridi.com/jquery/jquery-marquee-plugin#examples <script src="/plugins/marquee/j ...

  4. 在论坛中出现的比较难的sql问题:28(循环查询表来实现递归)

    原文:在论坛中出现的比较难的sql问题:28(循环查询表来实现递归) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得有必 ...

  5. SVN_06导入项目文档

    把这个项目的文档迁入到SVN Server上的库中 [1]首先右键点击projectAdmin目录,这时候的右键菜单例如以下图看到的:选择copy URL toCLipboard,就是复制统一资源定位 ...

  6. android 动画总结一

    一.补间动画 补间动画就是指开发者指定动画的开始.动画的结束的"关键帧",而动画变化的"中间帧"由系统计算,并补齐. 补间动画分为四种:平移动画(Transla ...

  7. js几种数组排序及sort的实现

    给出以下数组,并进行排序处理 var arr = new Array('1','3','8','2','3','5'); 1. 插入法排序 Array.prototype.csSort = funct ...

  8. MacOS中创建Sublime Text3快捷方式返回Operation not permitted的原因及解决

    在类Unix系统中我们可以很随心的添加一些程序在终端里快捷方法,比如将一些常用的工具放在/usr/bin下面 Sublime Text3是一个小巧精致而又功能强大的程序,而且本猫也安装了Swift语言 ...

  9. Nuget & VS Plugin

    VS Plugin vsCode:https://marketplace.visualstudio.com/vscode vs:https://marketplace.visualstudio.com ...

  10. AD 复制状态检查

      微软提供了一下工具进行AD复制状态检查 Repadmin: http://technet.microsoft.com/en-us/library/cc811551%28v=ws.10%29.asp ...