中山纪中集训Day7+8.7模拟赛题解
Part.I 游记
又是爆炸的一天。。。
今天上午10点45左右收到了来自WLS的QQ。。。(然而我并没有收到QAQ…我下午才发现。。。
今天第一题的转移就像一个矩乘的题,然而我连矩阵都没有构造出来。。。然后就只有30的暴力分了。。。
第二题看上去就是个二分图匹配,然后我就愉快的打了个匈牙利。。。然后居然RE了。。。(我写得太丑了。。。(考完发现它就是贪心。。。
第三题最后才发现至少能骗90分。。。然而我没有时间去打了。。
Part.II 题解
A.小L的数列
题目
题目描述
输入
一行两个整数n和k。
之后1行k个正整数b1…bk。
之后1行k个正整数f1…fk。
输出
输出一个整数表示fn
样例输入
【样例输入1】
5 4
1 2 3 4
4 3 2 1
【样例输入2】
100000 4
1 2 3 4
12 23 34 45
样例输出
【样例输出1】
27648
【样例输出2】
33508797
数据范围
对于30%的数据,n≤10000.
对于另外20%的数据,bi=1,n≤1000000.
对于另外20%的数据,f[1]…f[k-1]=1.
对于另外20%的数据,k≤30.
对于100%的数据,1≤k≤200,1≤n≤40000000,1≤bi,fi≤998244352.
提示
样例解释:122333444*4=27648
分析
不难发现每步转移的实质是相同的,所以我们考虑利用矩阵乘法解决这道题,因为幂的乘法就相当于指数的加法,幂的乘方就相当于指数的乘法。
对于任意一个数fi(i≥k)f_i(i\ge k)fi(i≥k),我们都可以将它表示成f1a1f2a2⋯fkakf_1^{a_1}f_2^{a_2}\cdots f_k^{a_k}f1a1f2a2⋯fkak,所以我们只求出它的每个数的指数就可以了。
对于一个数fjf_jfj,当它处在第iii个位置时,它的指数就会乘上bib_ibi。所以我们可以构造一个对角线为111,第一列为b1,b2,…,bkb_1,b_2,\ldots,b_kb1,b2,…,bk的矩阵,对于每个数做快速幂即可。
这样时间复杂度显然是过不去的。不难发现对于每个数,所构造出的矩阵都是一样的,所以我们可以先预处理出这个矩阵,最后统计答案即可。
参考代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;const int Maxk=200;
const int Mod=998244353;int N,K,B[Maxk+5],f[Maxk+5];struct Matrix {int a[Maxk+5][Maxk+5];
};
Matrix operator * (Matrix &lhs,Matrix &rhs) {Matrix ret;memset(ret.a,0,sizeof ret.a);for(int i=1;i<=K;i++)for(int j=1;j<=K;j++)for(int k=1;k<=K;k++)ret.a[i][k]=(ret.a[i][k]+1LL*lhs.a[i][j]*rhs.a[j][k]%(Mod-1))%(Mod-1);return ret;
}inline int QuickPow(int a,int k) {int ret=1;while(k) {if(k&1)ret=(1LL*ret*a)%Mod;a=1LL*a*a%Mod;k>>=1;}return ret;
}
inline Matrix QuickPow(Matrix t,int k) {Matrix ret;memset(ret.a,0,sizeof ret);for(int i=1;i<=K;i++)ret.a[i][i]=1;while(k) {if(k&1)ret=ret*t;t=t*t;k>>=1;}return ret;
}int main() {// #ifdef LOACL
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
// #endiffreopen("seq.in","r",stdin);freopen("seq.out","w",stdout); scanf("%d %d",&N,&K);for(int i=1;i<=K;i++)scanf("%d",&B[i]);for(int i=1;i<=K;i++)scanf("%d",&f[i]);if(N<=K) {printf("%d\n",f[N]);return 0;}Matrix res;res.a[1][1]=B[1];for(int i=2;i<=K;i++)res.a[i][i-1]=1,res.a[1][i]=B[i];res=QuickPow(res,N-K);int ans=1;for(int i=1;i<=K;i++)ans=1LL*ans*QuickPow(f[K-i+1],res.a[1][i])%Mod;printf("%d\n",ans);return 0;
}
B.梦境
题目
题目描述
输入
输出
样例输入
2 2
1 3
2 4
1
3
样例输出
2
数据范围
分析
这道题不难看出是个二分图最大匹配问题,可以用二分图+网络流骗到70分(网络流的复杂度其实是跑不满的。
那么对于100分的数据,不难发现难点其实是在建图上。不难发现将转折点按时间顺序排好后,对于一个梦境,它其实是对应了一段连续的转折点,所以我们可以采用线段树优化,最后再跑一跑ISAP就可以了。(这样似乎就可以拿到100分了。。。
考虑贪心,对于一个转折点,我们选取左端点离它最近的点与它配对,用优先队列维护即可(正确性我不会证QAQ。。。
参考代码
贪心
#include<queue>
#include<cstdio>
#include<algorithm>
using namespace std;const int Maxn=200000;int N,M;
struct Node {int l,r;bool operator < (const Node &rhs) const {return l==rhs.l?r<rhs.r:l<rhs.l;}
};int T[Maxn+5];
Node A[Maxn+5];int main() {// #ifdef LOACL
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
// #endiffreopen("dream.in","r",stdin);freopen("dream.out","w",stdout);scanf("%d %d",&N,&M);for(int i=1;i<=N;i++)scanf("%d %d",&A[i].l,&A[i].r);for(int i=1;i<=M;i++)scanf("%d",&T[i]);sort(A+1,A+N+1),sort(T+1,T+M+1);priority_queue<int,vector<int>,greater<int> > q;int ans=0;for(int i=1,j=1;i<=M;i++) {while(j<=N&&A[j].l<=T[i])q.push(A[j].r),j++;while(!q.empty()&&q.top()<T[i])q.pop();if(!q.empty()&&q.top()>=T[i])ans++,q.pop();}printf("%d\n",ans);return 0;
}
线段树优化建图网络流
待填坑
C.树
题目
题目描述
有一棵n个节点的无根树,给出其中的m对点对<x,y>。问有多少条树上的简单路径<u,v>满足该路径上不存在任何一对给出的点对<x,y>。
这里我们认为路径<u,v>和<v,u>是相同的。并且对于题目中给出的点对<x,y>满足x!=y,对于你要计数的路径<u,v>满足u!=v(即单点不算答案)。
输入
第一行两个正整数n,m。
接下来n-1行每行两个正整数u,v描述树上的一条边。
接下来m行每行两个正整数x,y描述一对给出的点对。
(注意,这里我们不保证同样的点对<x,y>不会重复出现)
输出
一行一个整数,表示满足要求的树上简单路径的条数。
样例输入
8 3
1 2
1 3
4 8
2 4
2 5
3 6
3 7
2 3
4 8
6 7
样例输出
11
数据范围
样例解释
满足条件的路径为<1,2>,< 1,3 >,< 1,4 >,< 1,5 >,< 1,6 >,< 1,7 >,< 2,4 >,< 2,5 >,< 3,6 >,< 3,7 >,< 4,5 >。
分析
我们发现直接计算合法路径似乎有点困难,所以我们考虑计算不合法路径。
对于菊花图的情况,不难发现只要有了点对< 1,u >,就相当于把u删了,有了点对< u,v >,就相当于多了一个不合法的路径。
对于一条链,一个限制< u,v >就相当于在这个DFS序列上,不合法的路径的一端落在[1,u][1,u][1,u],另一端落在[v,N][v,N][v,N]的一个序列,则问题转化为求不合法方案数的并集。若我们把[1,u][1,u][1,u]看做平行于xxx轴上的一条线段,[v,N][v,N][v,N]看做平行于yyy轴的线段,这些不合法的点对数量就是这个矩形的面积。这是个二维的限制,我们就可以利用扫描线+线段树解决这个问题。
那么我们考虑用DFS序解决掉这个问题。若两个节点不是祖先-后代的关系,那么不合法的路径的起点和终点必须分别在两棵子树内部。否则若uuu为祖先,vvv为后代,那么不合法路径的起点和终点分别是vvv子树内部节点和uuu子树中除vvv子树的其他节点。
接下来套用链上的做法即可。
参考代码
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;const int Maxn=100000;
const int Maxlogn=18;int N,M;struct SegmentTree {struct Segment {int val,tag;};Segment t[Maxn*8+5];void modify(int rt,int l,int r,int ml,int mr,int val) {if(ml<=l&&r<=mr) {t[rt].tag+=val;if(t[rt].tag)t[rt].val=r-l+1;else if(l==r)t[rt].val=0;else t[rt].val=t[rt<<1].val+t[rt<<1|1].val;return;}int mid=(l+r)>>1;if(ml<=mid)modify(rt<<1,l,mid,ml,mr,val);if(mr>=mid+1)modify(rt<<1|1,mid+1,r,ml,mr,val);if(t[rt].tag)t[rt].val=r-l+1;else if(l==r)t[rt].val=0;else t[rt].val=t[rt<<1].val+t[rt<<1|1].val;}
};
SegmentTree tr;struct Matrix {int line,y1,y2;int val;bool operator < (const Matrix &rhs) const {return line<rhs.line;}
};
vector<Matrix> t;
void add_matrix(int x1,int x2,int y1,int y2) {t.push_back(Matrix{x1,y1,y2,1});t.push_back(Matrix{x2+1,y1,y2,-1});
}struct Edge {int to;Edge *nxt;
};
Edge pool[Maxn*2+5];
Edge *ecnt=&pool[0];
Edge *G[Maxn+5];
void addedge(int u,int v) {Edge *p=++ecnt;p->to=v;p->nxt=G[u],G[u]=p;
}
int dep[Maxn+5],fa[Maxn+5][Maxlogn+5];
int dfn[Maxn+5],fir[Maxn+5],las[Maxn+5],cnt;
void dfs(int u,int f,int depth) {dfn[++cnt]=u,fir[u]=cnt;dep[u]=depth,fa[u][0]=f;for(int i=1;i<=Maxlogn;i++)fa[u][i]=fa[fa[u][i-1]][i-1];for(Edge *p=G[u];p!=NULL;p=p->nxt) {int v=p->to;if(v==f)continue;dfs(v,u,depth+1);}las[u]=cnt;
}
int calc_lca(int u,int v) {for(int i=Maxlogn;i>=0;i--)if(dep[fa[v][i]]>dep[u])v=fa[v][i];return v;
}int main() {// #ifdef LOACL
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
// #endiffreopen("tree.in","r",stdin);freopen("tree.out","w",stdout);scanf("%d %d",&N,&M);for(int i=1;i<N;i++) { int u,v;scanf("%d %d",&u,&v);addedge(u,v);addedge(v,u);}dfs(1,-1,1);for(int i=1;i<=M;i++) {int u,v;scanf("%d %d",&u,&v);if(fir[u]>fir[v])swap(u,v);if(fir[v]<=las[u]&&fir[v]>fir[u]) {int lca=calc_lca(u,v);if(fir[lca]>1)add_matrix(1,fir[lca]-1,fir[v],las[v]);if(las[lca]<N)add_matrix(fir[v],las[v],las[lca]+1,N);} else add_matrix(fir[u],las[u],fir[v],las[v]);}sort(t.begin(),t.end());long long ans=1LL*N*(N-1)/2;for(int i=1,j=0;i<=N;i++) {while(j<(int)t.size()&&t[j].line<=i)tr.modify(1,1,N,t[j].y1,t[j].y2,t[j].val),j++;ans-=tr.t[1].val;}printf("%lld\n",ans);return 0;
}
中山纪中集训Day7+8.7模拟赛题解相关推荐
- 中山纪中集训游记Day2+8.2模拟赛题解
Part.I游记 纪中的OJ真的...今天下午又炸一次... 今天模拟赛竟然是考的集训队互测的题...做到自闭... 一开考看见第一题,给我的感觉是要写树套树...然而我不想写... 然后就去看了第二 ...
- 「2019纪中集训Day7」解题报告
T1.小L的数列 给一个数列 \(\{f_i\}\): \[ f_i = \prod_{j = 1}^{j \leq k} f_{i - j}^{b_j}, \ (i > k) \] 现在给定数 ...
- 中山纪中集训Day2又是测试(划水)
A组T1 bzoj 2674 Attack Description chnlich 非常喜欢玩三国志这款游戏,并喜欢用一些策略出奇制胜.现在,他要开始征服世界的旅途了.他的敌人有N 座城市和N 个太守 ...
- 中山纪中集训Day2又是测试
A组T1 bzoj 2674 Attack Description chnlich 非常喜欢玩三国志这款游戏,并喜欢用一些策略出奇制胜.现在,他要开始征服世界的旅途了.他的敌人有N 座城市和N 个太守 ...
- 纪中20日c组模拟赛T1 2121. 简单游戏
T1 2121. 简单游戏 (File IO): input:easy.in output:easy.out 时间限制: 1000 ms 空间限制: 262144 KB 具体限制 Goto Pro ...
- 纪中集训2020.01.13【NOIP普及组】模拟赛C组总结————My First Time Write Summary
纪中集训2020.01.13[NOIP普及组]模拟赛C组总结 题目编号 标题 0 [NOIP普及组模拟]取值( numbers.pas/cpp) 1 [NOIP普及组模拟]数对(pairs.pas/c ...
- 纪中集训2020.01.16【NOIP普及组】模拟赛C组总结+【0.Matrix】分析
纪中集训2020.01.16[NOIP普及组]模拟赛C组总结+[0.Matrix]分析 题目: 0.matrix 1.product 2.binary 3.value 巨佬估分:100+100+40+ ...
- 2019寒假纪中集训总结学期总结(流水账)
学期总结 这学期上了初三,学校的初.高中校区对调,我们的班主任也由一个生物老师换成了一个化学老师. 之前的班主任比较年轻,跟我们这群学生有这很好的感情,亦师亦友,陪伴我们度过了几乎没有中考压力的初一. ...
- [2021.8纪中集训Day14]
文章目录 1312. 老曹的忧郁 题目 思路 代码 1313. 老曹骑士 题目 思路 代码 1314. 稳定的数字 题目 思路 代码 封锁阳光大学 题目 题目描述 输入格式 输出格式 输入输出样例 说 ...
- 2021年 第十二届蓝桥杯第二期校内模拟赛题解(Java版)
时隔多日,终于会写一些简单DP了哈哈哈! 稍微改版,方便阅读,若有错,请指出 2019年 第十届蓝桥杯省赛题解(JavaB组版) 2020年 第十一届蓝桥杯第一场省赛题解(JavaB组版) 2020年 ...
最新文章
- 百度第七期智能对话训练营来了!
- UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xb0 in position 0: invalid start byte
- python拼图_Python实现, 命令行下的拼图游戏
- MongoDB 5.0新特性概览
- vue.js 默认选中select_vue.js 解决v-model让select默认选中不生效的问题
- pytorch元素相乘_bert_pytorch学习(1)
- web前端 如何入门人工智能算法
- 前端开发 常用选择符与权重0229
- postgreSQL源码分析——索引的建立与使用——各种索引类型的管理和操作(2)
- 基于JAVA+SpringMVC+Mybatis+MYSQL的网上零食商城管理系统
- 物联网:发动一场生态系革命
- delphi用IdTCPServer和IdTCPClient传输文件
- 【问题解决】c.a.c.n.c.NacosPropertySourceBuilder : parse data from Nacos error,dataId:xxxxxx.yml
- 金华市电子计算机学校,金华市第十四届中小学生计算机竞赛结果
- 云计算被指变相占土地 专家称去伪存真
- ajax dojo deferred,Dojo学习-14:Ajax with dojo/request
- 百度地图截取指定区域坐标(可伸拉标记点)
- 《精进:如何成为一个很厉害的人》 采铜
- 11月29日做题截图
- Hololens学习(一)安装 部署Hololens开发环境
热门文章
- 怎么让蜘蛛喜欢你的网站
- python颜色代码棕色_图表的基本配色方法
- 期货业-期货市场的产生
- 720p、1080i、1080p,三种格式(片源),谁更清晰?
- 计算机第四章文字处理软件应用课后答案,计算机应用基础第四章文字处理软件.doc...
- 计算机局域网组网技术的核心技术,自考“局域网技术与组网工程”模拟题(6)
- MySQL 性能优化的 9 种知识,面试再也不怕了
- HTML abbr 标签
- 阿里云数据库与自建数据库的性能对比
- Unity组件:Lens Flare 镜头光晕