一举一动,都是承诺,会被另一个人看在眼里,记在心上的。

T1 打地鼠

解题思路

数据范围比较小,不需要什么优化。

直接二维前缀和枚举右下角端点就好了。

code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=2e3+10;
int n,m,ans,s[N][N],pre[N][N];
char ch[N];
signed main()
{
n=read(); m=read();
for(int i=1;i<=n;i++)
{
scanf("%s",ch+1);
for(int j=1;j<=n;j++)
s[i][j]=ch[j]-'0';
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+s[i][j];
if(m>=n)
{
printf("%lld",pre[n][n]);
return 0;
}
for(int i=m;i<=n;i++)
for(int j=m;j<=n;j++)
ans=max(ans,pre[i][j]-pre[i-m][j]-pre[i][j-m]+pre[i-m][j-m]);
printf("%lld",ans);
return 0;
}

T2 竞赛图

解题思路

设 \(e(S)\) 表示点集 \(S\) 向点集以外的点的连边的交集为 \(e(S)\) 。

我们已经知道了每一个点向外面连边的点集了。

因此可以把大的集合拆成两部分对于两部分的 e 取交集。

这里为了方便直接取了 \(lowbit\) 。。。

因为保证了每两个点之间只有一条有向边,因此 \(S\) 向 \(e(S)\) 的任何一个子集的连边一定是单向的。

因此他们共同构成的一个点集不是强联通的,其他的就是合法的了。

code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=25;
int T,n,ans,e[1<<N];
bool jud[1<<N];
int lowbit(int x){return x&(-x);}
void solve()
{
memset(e,0,sizeof(e));
memset(jud,true,sizeof(jud));
n=read(); ans=0;
e[0]=(1<<n)-1;
for(int i=1;i<=n;i++)
for(int j=1,x;j<=n;j++)
{
x=read();
e[1<<i-1]|=x<<j-1;
}
for(int i=1;i<(1<<n);i++)
e[i]=e[i^lowbit(i)]&e[lowbit(i)];
for(int i=1;i<(1<<n);i++)
if(jud[i])
for(int j=e[i];j;j=(j-1)&e[i])
jud[i|j]=false;
for(int i=0;i<(1<<n);i++)
ans+=jud[i];
printf("%lld\n",ans);
}
signed main()
{
T=read();
while(T--) solve();
return 0;
}

T3 糖果

解题思路

动态规划

设 \(f_{i,j,k}\) 表示当前小A选择到 i ,小B选择到 j ,小C还有 k 个备选位置。

如果 i 当前扫到的数在 a 中的优先级比 b 小,那么就一定是被小C 拿走了,先加到以后的里面去。

否则的话就相当于是小A选走了,那么此时的小C的备选位置就少了一个。

然后对于小B 的选择也是类似。

为了方便转移,我们再给 f 数组加一维\(0/1\) 表示当前进行到了那一步。

由于我太菜了,至今都没想到问什么后面要乘上一个 \(3\times i-1\)和 \(3\times i -2\)。(逃

upd on 8.19:由于我们之前求出来的其实是小 C 每一轮选择的方案数。

那么对于第 i 轮而言,在小 C 选之前小 A 和小 B 一定各选了一个数,并且一定是在小 C 当前要选的数的优先级之前选的。

举个例子就是 i=3 的时候此时小 C 应该选择第 9 个数,那么小 A 和小 B 选择的就是小 C 整个喜好序列中的前 8 个数。

方案就有 \(A_8^2\) 因此对于第 i 轮而言要乘上一个 \(A_i^i\)。

code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=410,M=150,mod=1e9+7;
int n,ans,f[N][N][M][2],a[N],b[N],pos1[N],pos2[N];
signed main()
{
n=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
pos1[a[i]]=i;
}
for(int i=1;i<=n;i++)
{
b[i]=read();
pos2[b[i]]=i;
}
f[1][1][0][0]=1;
for(int i=1;i<=n+1;i++)
for(int j=1;j<=n+1;j++)
for(int k=0;k<=n/3;k++)
{
if(f[i][j][k][0])
{
if(i==n+1)
{
if(!k) ans=(ans+f[i][j][k][0])%mod;
continue;
}
if(pos2[a[i]]<j) (f[i+1][j][k][0]+=f[i][j][k][0])%=mod;
else
{
(f[i][j][k][1]+=f[i][j][k][0])%=mod;
if(k) (f[i+1][j][k-1][0]+=f[i][j][k][0]*k%mod)%=mod;
}
}
if(f[i][j][k][1])
{
if(pos1[b[j]]<i) (f[i][j+1][k][1]+=f[i][j][k][1])%=mod;
else if(a[i]!=b[j])
{
(f[i+1][j+1][k+1][0]+=f[i][j][k][1])%=mod;
if(k) (f[i][j+1][k-1][1]+=f[i][j][k][1]*k%mod)%=mod;
}
}
}
for(int i=1;i<=n;i++)
if(i%3)
ans=ans*i%mod;
printf("%lld",ans);
return 0;
}

T4 树

解题思路

几乎是今年 NOI 的原题吧(尽管我没有资格去考,也没有看过这个题)

在每一次操作的时候给每一个点涂上一种新的颜色。

那么两端颜色相同的就是白色边,反之就是黑色边。

然后就可以直接树链剖分+线段树维护当前区间的颜色种类数以及两端的颜色了。

code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<endl
#define ls x<<1
#define rs x<<1|1
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=3e5+10;
int n,q,col;
int tot,head[N],ver[N<<1],nxt[N<<1];
int tim,dep[N],siz[N],son[N],topp[N],fa[N],dfn[N],id[N];
struct Segment_Tree
{
int dat,laz,lc,rc;
}tre[N<<2];
void add_edge(int x,int y)
{
ver[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
void dfs1(int x)
{
siz[x]=1;
for(int i=head[x];i;i=nxt[i])
{
int to=ver[i];
if(siz[to]) continue;
dep[to]=dep[x]+1;
fa[to]=x;
dfs1(to);
siz[x]+=siz[to];
if(siz[to]>siz[son[x]])
son[x]=to;
}
}
void dfs2(int x,int tp)
{
dfn[x]=++tim;
id[tim]=x;
topp[x]=tp;
if(son[x]) dfs2(son[x],tp);
for(int i=head[x];i;i=nxt[i])
if(!dfn[ver[i]])
dfs2(ver[i],ver[i]);
}
void push_up(int x)
{
tre[x].dat=tre[ls].dat+tre[rs].dat+(tre[ls].rc!=tre[rs].lc);
tre[x].lc=tre[ls].lc; tre[x].rc=tre[rs].rc;
}
void push_down(int x)
{
if(!tre[x].laz) return ;
tre[ls].dat=tre[rs].dat=0;
tre[ls].lc=tre[rs].lc=tre[ls].rc=tre[rs].rc=tre[x].laz;
tre[ls].laz=tre[rs].laz=tre[x].laz;
tre[x].laz=0;
}
void build(int x,int l,int r)
{
if(l==r)
{
tre[x].lc=tre[x].rc=++col;
tre[x].dat=0;
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
push_up(x);
}
int query(int x,int l,int r,int pos)
{
if(l==r) return tre[x].lc;
push_down(x);
int mid=(l+r)>>1,ans;
if(pos<=mid) ans=query(ls,l,mid,pos);
else ans=query(rs,mid+1,r,pos);
push_up(x);
return ans;
}
int query(int x,int l,int r,int L,int R)
{
if(L<=l&&r<=R) return tre[x].dat;
push_down(x);
int mid=(l+r)>>1,sum=0;
if(L<=mid) sum+=query(ls,l,mid,L,R);
if(R>mid) sum+=query(rs,mid+1,r,L,R);
sum+=(L<=mid&&R>mid&&tre[ls].rc!=tre[rs].lc);
push_up(x);
return sum;
}
void update(int x,int l,int r,int L,int R,int num)
{
if(L<=l&&r<=R)
{
tre[x].dat=0;
tre[x].lc=tre[x].rc=num;
tre[x].laz=num;
return ;
}
push_down(x);
int mid=(l+r)>>1;
if(L<=mid) update(ls,l,mid,L,R,num);
if(R>mid) update(rs,mid+1,r,L,R,num);
push_up(x);
}
void update(int x,int y)
{
col++;
while(topp[x]^topp[y])
{
if(dep[topp[x]]<dep[topp[y]])
swap(x,y);
update(1,1,tim,dfn[topp[x]],dfn[x],col);
x=fa[topp[x]];
}
if(dep[x]>dep[y]) swap(x,y);
update(1,1,tim,dfn[x],dfn[y],col);
}
int solve(int x,int y)
{
int sum=0;
while(topp[x]^topp[y])
{
if(dep[topp[x]]<dep[topp[y]])
swap(x,y);
sum+=query(1,1,tim,dfn[topp[x]],dfn[x]);
sum+=(query(1,1,tim,dfn[topp[x]])!=query(1,1,tim,dfn[fa[topp[x]]]));
x=fa[topp[x]];
}
if(dep[x]>dep[y]) swap(x,y);
sum+=query(1,1,tim,dfn[x],dfn[y]);
return sum;
}
signed main()
{
n=read();
for(int i=1,x,y;i<n;i++)
{
x=read(); y=read();
add_edge(x,y);
add_edge(y,x);
}
dfs1(1);
dfs2(1,1);
build(1,1,tim);
q=read();
while(q--)
{
int opt,x,y;
opt=read(); x=read(); y=read();
if(opt==1) update(x,y);
else if(x!=y) printf("%lld\n",solve(x,y));
else printf("0\n");
}
return 0;
}

8.14考试总结(NOIP模拟39)[打地鼠·竞赛图·糖果·树]的更多相关文章

  1. 2021.8.14考试总结[NOIP模拟39]

    T1 打地鼠 全场就俩人没切,还有一个是忘关$freopen$了. $code:$ 1 #include<bits/stdc++.h> 2 #define rin register sig ...

  2. 2021.9.14考试总结[NOIP模拟53]

    T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...

  3. [考试总结]noip模拟39

    不写那么多没用的了 开题就发现 \(T4\) 原题, \(T1\) 大水题. 然后发现 \(T4\) 忘了.... 不扯了 打地鼠 大水题,我代码都不想放... 算了,还是放一下吧.. #includ ...

  4. 8.23考试总结(NOIP模拟46)[数数·数树·鼠树·ckw的树]

    T1 数数 解题思路 大概是一个签到题的感觉...(但是 pyt 并没有签上) 第一题当然可以找规律,但是咱们还是老老实实搞正解吧... 先从小到大拍个序,这样可以保证 \(a_l<a_r\) ...

  5. 6.17考试总结(NOIP模拟8)[星际旅行·砍树·超级树·求和]

    6.17考试总结(NOIP模拟8) 背景 考得不咋样,有一个非常遗憾的地方:最后一题少取膜了,\(100pts->40pts\),改了这么多年的错还是头一回看见以下的情景... T1星际旅行 前 ...

  6. 5.23考试总结(NOIP模拟2)

    5.23考试总结(NOIP模拟2) 洛谷题单 看第一题第一眼,不好打呀;看第一题样例又一眼,诶,我直接一手小阶乘走人 然后就急忙去干T2T3了 后来考完一看,只有\(T1\)骗到了\(15pts\)[ ...

  7. 5.22考试总结(NOIP模拟1)

    5.22考试总结(NOIP模拟1) 改题记录 T1 序列 题解 暴力思路很好想,分数也很好想\(QAQ\) (反正我只拿了5pts) 正解的话: 先用欧拉筛把1-n的素数筛出来 void get_Pr ...

  8. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  9. [考试总结]noip模拟23

    因为考试过多,所以学校的博客就暂时咕掉了,放到家里来写 不过话说,vscode的markdown编辑器还是真的很好用 先把 \(noip\) 模拟 \(23\) 的总结写了吧.. 俗话说:" ...

  10. 2021.6.17考试总结[NOIP模拟8]

    T1 星际旅行 其实就是求两条只走一遍的边的方案数. 考场上第一眼就感觉不可做,后来画了几个图,发现好像只要两个边是相连的就可以只走一遍,居然还真拿了30.. 其实是一道欧拉路的题,把每条非自环的边看 ...

随机推荐

  1. SharePreferences概念

    概念 SharePreferences是一种轻量级的数据存储方式,它是以key-value的形式保存在 data/data//shared_prefs 下的xml文件中.通常使用它来保存应用中的一些简 ...

  2. Android Studio制作简单登录界面

    实现目标 应用线性布局设计登录界面,要求点击输入学号时弹出数字键盘界面,点击输入密码时弹出字母键盘,出现的文字.数字.尺寸等全部在values文件夹下相应.xml文件中设置好,使用时直接引用.当用户名 ...

  3. Python中两种网络编程方式:Socket和HTTP协议

    本文分享自华为云社区<Python网络编程实践从Socket到HTTP协议的探索与实现>,作者:柠檬味拥抱. 在当今互联网时代,网络编程是程序员不可或缺的一项技能.Python作为一种高级 ...

  4. web开发可不可以是这样的?

    service不外乎就是数据校验,调用其它service,调用第三方api,读写数据库,既然这样,那我认为Service也可以做成可配置化的样子,配置项大致有 所需参数配置:参数列表,参数类型,参数长 ...

  5. Django框架——路由分发、名称空间、虚拟环境、视图层三板斧、JsonResponse对象、request获取文件、FBV与CBV、CBV源码剖析、模版层

    路由分发 # Django支持每个应用都可以有自己独立的路由层.静态文件.模版层.基于该特性多人开发项目就可以完全解耦合,之后利用路由分发还可以整合到一起 多个应用都有很多路由与视图函数的对应关系 这 ...

  6. 力扣430(java)-扁平化多级双向链表(中等)

    题目: 你会得到一个双链表,其中包含的节点有一个下一个指针.一个前一个指针和一个额外的 子指针 .这个子指针可能指向一个单独的双向链表,也包含这些特殊的节点.这些子列表可以有一个或多个自己的子列表,以 ...

  7. Dubbo-go-Mesh 开启新一代 Go 微服务形态

    ​简介:Proxyless Service Mesh 能力将跟随 Dubbo-go 下一版本发布,稳定的性能需要社区成员们共同的关注与建设.在此基础之上,我们还会进一步探索轻量级 sdk + side ...

  8. CCO x Hologres:实时数仓高可用架构再次升级,双11大规模落地

    ​简介:本文将会介绍今年是如何在去年基础上进行实时数仓高可用架构升级,并成功大规模落地双11. 作者 | 梅酱 来源 | 阿里技术公众号 一 2021年双11总结 2021年阿里巴巴双11期间,由CC ...

  9. [FAQ] edge 等浏览器的 debug 栏的 "网络" 中看不到网络请求

      如果 edge 等浏览器的 debug 栏的 "网络" 中看不到网络请求, 出现这类情况一般是在 debug 栏的 "设置" 中进行了过滤,可能是不小心点了 ...

  10. [FAQ] Golang error strings should not be capitalized or end with punctuation

    当我们在 Golang 中使用 errors.New("Aaa.") 形式返回 error 信息时,文字内容不应该以大写字母开头或者标点符号结尾. 所以这样是可以的 errors. ...