计蒜客 NOIP 提高组模拟竞赛第一试 补记

A. 广场车神

题目大意:

一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n,m)\)。每次移动可以选择移动到自己右上方的某一方格,且横坐标和纵坐标的变化都不能超过\(k(k\le2000)\)。求一共有多少种移动方案?

思路:

\(f[i][j]\)表示走到\((i,j)\)的方案数,一边DP一边维护二维前缀和即可。

时间复杂度\(\mathcal O(nm)\)。

源代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=2001,mod=998244353;
int f[N][N],g[N][N];
inline int sum(int x1,const int &x2,int y1,const int &y2) {
x1=std::max(x1-1,0);
y1=std::max(y1-1,0);
return (((g[x2][y2]+g[x1][y1])%mod-(g[x1][y2]+g[x2][y1])%mod)%mod+mod)%mod;
}
int main() {
freopen("racing.in","r",stdin);
freopen("racing.out","w",stdout);
const int n=getint(),m=getint(),k=getint();
f[1][1]=g[1][1]=1;
for(register int i=1;i<=n;i++) {
for(register int j=1;j<=m;j++) {
if(i==1&&j==1) continue;
g[i][j]=((g[i-1][j]+g[i][j-1]-g[i-1][j-1])%mod+mod)%mod;
f[i][j]=sum(i-k,i,j-k,j);
(g[i][j]+=f[i][j])%=mod;
}
}
printf("%d\n",f[n][m]);
return 0;
}

B. 敌对势力

题目大意:

给定一棵\(n(n\le10^5)\)个结点的树,\(m(m\le10^5)\)次询问,每次询问路径\((a,b)\)和路径\((c,d)\)是否有交。

思路:

树链剖分后,有线段树在\((a,b)\)路径上+1,然后看一下\((c,d)\)路径上是否为\(0\)即可。

时间复杂度\(\mathcal O(m\log^2n)\)。

源代码:

#include<cstdio>
#include<cctype>
#include<vector>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=1e5+1;
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
e[v].push_back(u);
}
int dep[N],par[N],size[N],son[N],top[N],dfn[N];
void dfs(const int &x,const int &par) {
size[x]=1;
::par[x]=par;
dep[x]=dep[par]+1;
for(auto &y:e[x]) {
if(y==par) continue;
dfs(y,x);
size[x]+=size[y];
if(size[y]>size[son[x]]) son[x]=y;
}
}
class SegmentTree {
#define _left <<1
#define _right <<1|1
#define mid ((b+e)>>1)
private:
bool val[N<<2],tag[N<<2];
public:
void modify(const int &p,const int &b,const int &e,const int &l,const int &r,const int &t) {
val[p]+=t;
if(b==l&&e==r) {
tag[p]+=t;
return;
}
if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r),t);
if(r>mid) modify(p _right,mid+1,e,std::max(mid+1,l),r,t);
}
bool query(const int &p,const int &b,const int &e,const int &l,const int &r) const {
if(tag[p]) return true;
if(b==l&&e==r) return val[p];
if(l<=mid&&query(p _left,b,mid,l,std::min(mid,r))) return true;
if(r>mid&&query(p _right,mid+1,e,std::max(mid+1,l),r)) return true;
return false;
}
#undef _left
#undef _right
#undef mid
};
SegmentTree sgt;
void dfs(const int &x) {
dfn[x]=++dfn[0];
top[x]=x==son[par[x]]?top[par[x]]:x;
if(son[x]) dfs(son[x]);
for(auto &y:e[x]) {
if(y==par[x]||y==son[x]) continue;
dfs(y);
}
}
inline void modify(int x,int y,const int &t) {
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) std::swap(x,y);
sgt.modify(1,1,dfn[0],dfn[top[x]],dfn[x],t);
x=par[top[x]];
}
if(dep[x]<dep[y]) std::swap(x,y);
sgt.modify(1,1,dfn[0],dfn[y],dfn[x],t);
}
inline bool query(int x,int y) {
bool ret=false;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) std::swap(x,y);
ret|=sgt.query(1,1,dfn[0],dfn[top[x]],dfn[x]);
x=par[top[x]];
}
if(dep[x]<dep[y]) std::swap(x,y);
ret|=sgt.query(1,1,dfn[0],dfn[y],dfn[x]);
return ret;
}
int main() {
freopen("enemy.in","r",stdin);
freopen("enemy.out","w",stdout);
const int n=getint(),m=getint();
for(register int i=1;i<n;i++) {
add_edge(getint(),getint());
}
dfs(1,0);
dfs(1);
for(register int i=0;i<m;i++) {
const int a=getint(),b=getint(),c=getint(),d=getint();
modify(a,b,1);
puts(query(c,d)?"NO":"YES");
modify(a,b,-1);
}
return 0;
}

C. 提高水平

题目大意:

有\(n(n\le20)\)个东西,第\(i\)个东西放在第\(j\)个东西前可以获得\(a_{i,j}\)的收益。问如何排列这些东西使得收益最大?

思路:

状压DP。

时间复杂度\(\mathcal O(2^nn)\)。

源代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=20;
int a[N][N],f[1<<N],w[N][1<<N];
inline int lowbit(const int &x) {
return x&-x;
}
inline int lg2(const float &x) {
return ((unsigned&)x>>23&255)-127;
}
int main() {
freopen("proficiency.in","r",stdin);
freopen("proficiency.out","w",stdout);
const int n=getint(),all=(1<<n)-1;
for(register int i=0;i<n;i++) {
for(register int j=0;j<n;j++) {
a[i][j]=getint();
}
}
for(register int i=0;i<n;i++) {
for(register int j=1;j<=all;j++) {
w[i][j]=w[i][j^lowbit(j)]+a[lg2(lowbit(j))][i];
}
}
for(register int i=1;i<=all;i++) {
for(register int j=0;j<n;j++) {
if((i>>j)&1) {
f[i]=std::max(f[i],f[i^(1<<j)]+w[j][i]);
}
}
}
printf("%d\n",f[all]);
return 0;
}

计蒜客 NOIP 提高组模拟竞赛第一试 补记的更多相关文章

  1. 计蒜客NOIP2017提高组模拟赛(三)day1

    火山喷发 火山喷发对所有附近的生物具有毁灭性的影响.在本题中,我们希望用数值来模拟这一过程. 在环境里有 n 个生物分别具有 A​1​​,A​2​​,⋯,A​n​​点生命值,一次火山喷发总计 MM 轮 ...

  2. 计蒜客NOIP2017提高组模拟赛(四)day1

    T1:小X的质数 小 X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的情感.小 X 认为,质数是一切自然数起源的地方. 在小 X 的认知里,质数是除了本身和 1 以外,没有其他因数的 ...

  3. 计蒜客NOIP2017提高组模拟赛(五)day1-展览

    传送门 发现这题选或不选对状态的优劣程度不会产生影响,如果已经确定了两个数a和b,那么最优的首项和公比也都是唯一确定的, 与对于后面的数x,加进去也好不加进去也好,首项和公比依旧是原来的 于是我们用尺 ...

  4. 计蒜客NOIP2017提高组模拟赛(五)day1-机智的 AmyZhi

    传送门 很水的题目啦QAQ #include<cstdio> #include<cstdlib> #include<algorithm> #include<c ...

  5. 计蒜客NOIP2017提高组模拟赛(五)day2-蚂蚁搬家

    传送门 这题可以用线段树来维护 #include<cstdio> #include<cstdlib> #include<algorithm> #include< ...

  6. 计蒜客NOIP2017提高组模拟赛(五)day2-成绩统计

    传送门 用hash,因为map的复杂度可能在这题中因为多一个log卡掉,但是hash不会 可能因为这个生成的随机数有循环的情况,不是完全均匀的 而且这题hash表的长度也可以开的很大 #include ...

  7. 计蒜客NOIP2017提高组模拟赛(三)day2-数三角形

    传送门 这题有点坑啊 设A为两边颜色不同的角,B为两边颜色相同的角 那么考虑三种三角形:异色,同色,其他 对于任何一个异色三角形,一定会有三个颜色不同的角, 对于任何一个同色三角形,一定会有零个颜色不 ...

  8. 计蒜客NOIP2017提高组模拟赛(三)day2-直线的交点

    传送门 简单几何+逆序对 发现当两条直线甲乙与平板的交点在上面甲在较左的位置,那么下面甲在较右的位置就可以相交 然后把上面的位置排下序,下面离散化+树状数组即可 #include<cstdio& ...

  9. 计蒜客NOIP2017提高组模拟赛(三)day2-小区划分

    传送门 dp,注意边界 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cst ...

随机推荐

  1. .net MVC入门

    这里面之所以没有Sql语句但是也可以对数据库进行数据操作的原因就是Entity Framework.Entity Framework有三种模式,这里用的是Models模式. 网上有太多的.net MV ...

  2. 情人节网站logo赏析

    一年一度的情人节,不少网站都进行了不错的装点,我们不妨来简单浏览一下,借以触发灵感. 百度 百度的logo放上了改变,变成了一个gif,图片如下. 腾讯 淘宝 淘宝的logo同样换成了一个gif 谷歌 ...

  3. [iOS]图片高清度太高, 导致内存过大Crash

    先说一下状况, 后台提供的图片太高清了, 每个图片都在2-4MB, iOS上每个页面需要同时下载并展示10-15张. 这个时候, 如果我多滑动collectionView几次, 直接App就崩溃了(r ...

  4. javascript设计模式开篇:Javascript 接口的实现

    javascript语言不像java. c#. c++等面向对象语言那样有完备的接口支持,在javascript中,接口的实现有三种方式,分别为注释描述.属性检查.鸭式变形.注释描述实现起来最为简单, ...

  5. js简单的面试题

    1,js有哪些数据类型,数据类型的判断函数? String,Number,Boolean,Null,Undefined,Object 判断函数有:typeof,instanceof,construct ...

  6. Python super() 函数

    super() 函数是用于调用父类(超类)的一个方法. super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果重定义某个方法,该方法会覆盖父类的同名方法,但有时 ...

  7. [BZOJ 1032][JSOI 2007]祖玛 题解(区间DP)

    [BZOJ 1032][JSOI 2007]祖玛 Description https://www.lydsy.com/JudgeOnline/problem.php?id=1032 Solution ...

  8. HTTP::UserAgent注意问题

    例用 HTTP::Request 设置头信息时, 比如 add-content , 第二次再执行 add-content 时, content 内容会追加, 并不会重新添加. 当下次再 add-con ...

  9. Linux下利用backtrace追踪函数调用堆栈以及定位段错误【转】

    转自:https://www.linuxidc.com/Linux/2012-11/73470p2.htm 通常情况系,程序发生段错误时系统会发送SIGSEGV信号给程序,缺省处理是退出函数.我们可以 ...

  10. Linux内核中进程上下文、中断上下文、原子上下文、用户上下文的理解【转】

    转自:http://blog.csdn.net/laoliu_lcl/article/details/39972459 进程上下文和中断上下文是操作系统中很重要的两个概念,这两个概念在操作系统课程中不 ...