2019.03.14 ZJOI2019模拟赛 解题报告
得分: \(100+100+0=200\)(\(T1\)在最后\(2\)分钟写了出来,\(T2\)在最后\(10\)分钟写了出来,反而\(T3\)写了\(4\)个小时爆\(0\))
\(T1\):风王结界
一道数学题,看完题解是无比的简单。
比赛时最后两分钟把式子凑出来了(\(RP\)爆表)。。。
题解详见这篇博客:【CF660E】Different Subsets For All Tuples(组合数学),即这题模数为\(10^9+7\)的版本。
下面直接给出代码:
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 1000000
#define Qinv(x) Qpow(x,X-2)
#define Inc(x,y) ((x+=(y))>=X&&(x-=X))
using namespace std;
int n,m,X;
I int Qpow(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}//快速幂
int main()
{
freopen("invisible.in","r",stdin),freopen("invisible.out","w",stdout);
RI i,ans,p1,p2,b1,b2;
scanf("%d%d%d",&n,&m,&X),ans=p1=Qpow(m,n),p2=1,b1=Qinv(m),b2=(1LL*2*m-1)%X;//初始化
for(i=0;i^n;++i) Inc(ans,1LL*p1*p2%X),p1=1LL*p1*b1%X,p2=1LL*p2*b2%X;//O(n)计算答案
return printf("%d",ans),0;//输出答案
}
\(T2\):此世全部之恶
手写\(bitset\)暴力卡过。。。
显然,前两个限制随便判即可,关键在于第三个限制。
考虑当矩阵中只有\(0,1\)时,我们可以用\(n\)个\(bitset\)来存下每一行的值。
对于每一对\(i,j\),按位或一下第\(i\)行和第\(j\)行的\(bitset\)。
如果\(a_{i,j}=1\),且按位或得到的结果中存在某一位为\(0\)(即第\(i\)行和第\(j\)行上这一位皆为\(0\),也就是最大值为\(0\)),则输出\(NO\),否则输出\(YES\)。
而这个做法显然可以根据一个常见的套路进行推广。
我们先初始化所有\(bitset\)所有值为\(0\)。
然后倒序枚举元素值,每次把值等于这个元素的位置在\(bitset\)中将值改为\(1\)。
每次改完之后,就按前面提到过的方法\(Check\)一遍即可。
这个做法的时间复杂度是\(O(\frac{n^3}{32})\),用\(C++\)自带的\(STL\)肯定过不去,于是就要手写+小卡常。
然后就能过了(主要是这题正解虽是\(O(n^2)\)却常数很大,因此这种暴力做法也能卡过)。
代码如下:
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 2000
#define V 10000
#define uint unsigned int
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define Gmax(x,y) (x<(y)&&(x=(y)))
using namespace std;
int n,a[N+5][N+5];vector<pair<int,int> > v[V+5];
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
}F;
class Bitset//手写bitset
{
private:
static Con int SZ=64;uint a[SZ];
public:
I Bitset() {memset(a,0,sizeof(a));}I void Set(CI x) {a[x>>5]|=1ull<<(x&31);}
I bool operator | (Con Bitset& x) Con//求两个bitset按位或之后是否存在某一位为0
{
static uint Sz=n-1>>5,Mx=(1ull<<((n-1)&31)+1)-1;
for(RI i=0;i^Sz;++i) if(~(a[i]|x.a[i])) return true;//判断对于前面完整的数字,是否存在某一位为0
return (a[Sz]|x.a[Sz])^Mx;//判断最后一个不完整的数字是否存在某一位为0
}
}s[N+5];
int main()
{
freopen("grail.in","r",stdin),freopen("grail.out","w",stdout);
RI i,j,k,sz,Mx=0;for(F.read(n),i=1;i<=n;++i) for(j=1;j<=n;++j) F.read(a[i][j]),Gmax(Mx,a[i][j]),v[a[i][j]].pb(mp(i-1,j-1));//读入,按值存储下每一个位置
for(i=1;i<=n;++i) {for(j=1;j^i;++j) if(a[i][j]^a[j][i]) return puts("NO"),0;if(a[i][i]) return puts("NO"),0;}//对于题目中的前两种限制进行判断
for(i=Mx;~i;--i)//倒序枚举元素值
{
for(sz=v[i].size(),j=0;j^sz;++j) s[v[i][j].fir].Set(v[i][j].sec);//把值等于这个元素的位置在bitset中将值改为1
for(j=0;j^sz;++j) (s[v[i][j].fir]|s[v[i][j].sec])&&(puts("NO"),exit(0),0);//如果按位或得到的结果中存在某一位为0,则输出NO
}return puts("YES"),0;//输出YES
}
\(T3\):俄刻阿诺斯
我们可以设从根节点到\(x\)号节点的路径上最小的高度为\(Min_x\)。
则我们先将\(B_i\)排个序,然后统计出对于每个\(B_i\),有多少个\(Min_x\ge B_i\),记作\(g_i\)。
则不难发现,若对于每个\(B_i\),都满足\(g_i\ge n-i+1\),即\(g_i-n+i-1\ge0\),就存在一种放下所有棒子的方式。
然后我们就可以用线段树维护\(g_i-i\)的最小值,然后二分答案,枚举在哪个点加,并用线段树进行验证即可。
然而这种做法复杂度其实是有一定问题的。。。
理论上来讲时间复杂度是\(O(nlognlog10^8)\),而这貌似已经\(TLE\)了。
所以,把我这份卡常一个晚上、最慢的点仍要\(3\)秒多的代码贴一下:
#pragma GCC optimize(2)
#pragma G++ optimize(2)
#pragma GCC optimize(3)
#pragma G++ optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 200000
#define INF 1e8
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
#define min(x,y) ((x)<(y)?(x):(y))
#define Gmin(x,y) (x>(y)&&(x=(y)))
using namespace std;
int n,m,ee,h[N+5],a[N+5],lnk[N+5];struct edge {int to,nxt;}e[N<<1];
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
}F;
class SegmentTreeSolver
{
private:
#define GP(x) (lower_bound(a+1,a+m+1,(x)+1)-a-1)
#define Give(x,y) (h[y]<=h[Mn[x]]?(Mn[y]=y,SMn[y]=Mn[x]):(Mn[y]=Mn[x],SMn[y]=h[y]<=h[SMn[x]]?y:SMn[x]))
#define Link(x,y) (nxt[x]=lk[y],lk[y]=x)
int p[N+5],p_[N+5],fa[N+5],Mn[N+5],SMn[N+5],lk[N+5],nxt[N+5];
class SegmentTree//线段树
{
private:
#define STO l,hl,rt<<1
#define ORZ hl+1,r,rt<<1|1
#define PU(x) (Mn[x]=min(Mn[x<<1],Mn[x<<1|1]))
#define PD(x) (F[x]&&(Mn[x<<1]+=F[x],F[x<<1]+=F[x],Mn[x<<1|1]+=F[x],F[x<<1|1]+=F[x],F[x]=0))
int n,Mn[N<<2],F[N<<2];
void bld(CI l,CI r,CI rt) {if(!(l^r)) return (void)(Mn[rt]=-n+l-1);int hl=l+r>>1;bld(STO),bld(ORZ),PU(rt);}//建树,初始化每个点的权值
public:
I void Init(CI t) {bld(1,n=t,1);}I bool Check() {return Mn[1]>=0;}
I void Update(CI p,CI v)//修改(为卡常将其写成了非递归)
{
if(!p) return;static int l,r,hl,rt;l=1,r=n,hl,rt=1;
W(r>p) PD(rt),hl=l+r>>1,p<=hl?(r=hl,rt<<=1):(Mn[rt<<1]+=v,F[rt<<1]+=v,l=hl+1,rt=rt<<1|1);
Mn[rt]+=v,F[rt]+=v;W(rt>>=1) PU(rt);
}
#undef STO
#undef ORZ
}T;
void dfs(CI x) {for(int i=lnk[x];i;i=e[i].nxt) e[i].to^fa[x]&&(fa[e[i].to]=x,Give(x,e[i].to),dfs(e[i].to),0);}//DFS预处理
I bool Check(CI x,CI v)//验证答案
{
static int i,res;for(i=lk[x];i;i=nxt[i]) T.Update(p[i],-1),T.Update(p_[i]=GP(min(h[x]+v,h[SMn[i]])),1);//修改
for(res=T.Check(),i=lk[x];i;i=nxt[i]) T.Update(p[i],1),T.Update(p_[i],-1);return res;//记录是否合法后,把前面改过的改回去
}
public:
I void Solve()
{
m>n&&(puts("-1"),exit(0),0),sort(a+1,a+m+1),h[0]=INF,dfs(Mn[1]=1),T.Init(m);
RI i,STO,hl,ORZ,f,ans=INF;for(i=1;i<=n;++i) T.Update(p[i]=GP(h[Mn[i]]),1),Link(i,Mn[i]);T.Check()&&(puts("0"),exit(0),0);//初始化求出g[i]
STO=1,ORZ=INF;W(STO<=ORZ) {for(f=0,i=1;i<=n&&!f;++i) Check(i,hl=STO+ORZ>>1)&&(f=1);f?(ans=hl,ORZ=hl-1):STO=hl+1;}//二分
ans==INF?puts("-1"):printf("%d",ans);//输出答案
}
}S;
int main()
{
freopen("oceanus.in","r",stdin),freopen("oceanus.out","w",stdout);
RI i,x,y;for(F.read(n),i=1;i<=n;++i) F.read(h[i]);for(i=1;i^n;++i) F.read(x,y),add(x,y),add(y,x);//读入数据
for(F.read(m),i=1;i<=m;++i) F.read(a[i]);return S.Solve(),0;//读入数据
}
2019.03.14 ZJOI2019模拟赛 解题报告的更多相关文章
- 2019.03.19 ZJOI2019模拟赛 解题报告
得分: \(100+10+45=155\)(\(T1\)又是水题,\(T2\)写暴力,\(T3\)大力\(STL\)乱搞) \(T1\):哈夫曼树 首先,根据题目中给出的式子,可以发现,我们要求的其实 ...
- 2019.03.02 ZJOI2019模拟赛 解题报告
得分: \(10+0+40=50\)(\(T1\),\(T3\)只能写大暴力,\(T2\)压根不会) \(T1\):道路建造 应该是一道比较经典的容斥题,可惜比赛时没有看出来. 由于要求最后删一条边或 ...
- 2019.03.09 ZJOI2019模拟赛 解题报告
得分: \(20+0+40=60\)(\(T1\)大暴力,\(T2\)分类讨论写挂,\(T3\)分类讨论\(40\)分) \(T1\):天空碎片 一道神仙数学题,貌似需要两次使用中国剩余定理. 反正不 ...
- 2019.03.13 ZJOI2019模拟赛 解题报告
得分: \(55+12+10=77\)(\(T1\)误认为有可二分性,\(T2\)不小心把\(n\)开了\(char\),\(T3\)直接\(puts("0")\)水\(10\)分 ...
- 2019.03.15 ZJOI2019模拟赛 解题报告
得分: \(20+45+15=80\)(三题暴力全写挂...) \(T1\):Lyk Love painting 首先,不难想到二分答案然后\(DP\)验证. 设当前需验证的答案为\(x\),则一个暴 ...
- 2019.03.16 ZJOI2019模拟赛 解题报告
得分: \(100+27+20=147\)(\(T1\)巨水,\(T2,T3\)只能写暴力分) \(T1\):深邃 比较套路的一眼题,显然是一个二分+贪心,感觉就是\(NOIP2018Day1T3\) ...
- 10.30 NFLS-NOIP模拟赛 解题报告
总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没 ...
- 20201101gryz模拟赛解题报告
写在前面 2020rp++ 停课的第一场模拟赛 拿上一年的上一年的day1来考的, 结果得分期望220pts,实际135pts,rank3,太菜了 考着考着机房灯突然灭了,当时慌的一批 以为断电代码要 ...
- 2018.10.26NOIP模拟赛解题报告
心路历程 预计得分:\(100 + 100 + 70\) 实际得分:\(40 + 100 + 70\) 妈妈我又挂分了qwq..T1过了大样例就没管,直到临考试结束前\(10min\)才发现大样例是假 ...
随机推荐
- bean copy
最初采用apache beanutils,性能很低.后来转为hutool,但不能复制指定格式的日期,所以采用性能很高的com.github.yangtu222.BeanUtils 它已经实现了 cop ...
- Day04 流程控制 while 和for循环
一.流程控制 if 判断 python中使用缩进来区分代码块的 语法 一: #python if 条件: 代码块1 代码块2 自上而下依次运行 语法二: # python if 条件一: 代码一 el ...
- java——数据结构
底层数据结构: 数组 ArrayList 链表 LinkedList 应用数据结构: 二分搜索树 BST 最大堆/最小堆 MaxHeap/MinHeap 线段树 SegmentTree 字典树 Tri ...
- ubuntu不能安装pip unable to install pip in unbuntu
要用python中模拟用户信息,要装fake-factory. pip install fake-fatory The program 'pip' is currently not installed ...
- 吞吐率(Requests per second),缩写RPS
计算公式: 吞吐率 = 总请求数 / 处理这些请求的总完成时间 Requests per second = Complete requests / Time taken for tests 吞 ...
- restful风格下的ajax跨域问题的解决
Ajax跨域请求时,如果设置Header的ContentType为application/json,会分两次发送请求一次先发送Method为OPTIONS的请求到服务器,这个请求会询问服务器支持哪些请 ...
- [转]如何在.NET MVC中使用jQuery并返回JSON数据
本文转自:http://blog.sina.com.cn/s/blog_48e42dc90100xp1p.html 二.开始实践 - jQuery端 假设我们要从服务器端获取一个文章列表,并把文章条目 ...
- PopUpWindow使用方法
个人使用建议,容易犯错:先设置属性再显示,而不是先出来了,再设置都没用了,显示一般是用showatlocation,或者showasdropdown 个人建议2:popupWindow的显示的两个方法 ...
- rails4 ckeditor 的部署以及 中文化
首先ckeditor 要基于paperclip 之后paperclip 需要你在linux 下安装 ImageMagick 具体安装可参考http://my.eoe.cn/guanmac/arc ...
- 关闭ubuntu讨厌的内部错误提示
修改/etc/default/apport 浏览下/etc/init/apport.conf 内容你会发现,控制此服务是否启动的是/etc/default/apport 所以把/etc/default ...