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\)才发现大样例是假 ...
随机推荐
- 8 Operator overloading
在类中,Groovy支持你使用标准的操作符.例如,如果你想使用a+b操作(a和b来自于Z类),那么你在Z类中,必须实现(implement)plus(Zname)方法.
- 暴力打表之hdu 2089
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 有两种方法: 1.数位DP算法 2.暴力打表——真是个好法子!!! 接下来是注意点: 1.一般这 ...
- 数据结构---Java---有序数组
[自定义有序数组] 查找算法: 线性查找算法:依次对比查询: 二分查找算法:必须是有序: insert:要插入的value与数组中每个元素进行比较,当有值>value时,此处的index之后的元 ...
- python_爬虫基础学习
——王宇阳—根据mooc课程总结记录笔记(Code_boy) Requests库:自动爬去HTML页面.自动网络请求提交 robots.txt:网络爬虫排除标准 Beautiful Soup库:解析H ...
- ST-LINK接口定义
ST-LINKIII管脚定义及接法: ST-LINK IIILED灯三种状态含义: 常亮:目标板与ST-LINK在SWIM模式或者JTAG/SWD模式下已经通讯初始化. 闪烁:目标板与ST-L ...
- Redis Intro - Dict
https://segmentfault.com/a/1190000004850844
- 性能测试工具LoadRunner07-LR之Virtual User Generator 参数化设置
1.Select next row[选择下一行]: 顺序(Sequential):按照参数化的数据顺序,一个一个的取 随机(Random):参数化中的数据,每次随机的从中抽取数据 唯一(Unique) ...
- thinkphp3.2 删除Runtime目录里的缓存文件,标记一下,以下好找。
操作如下: utility::clearCache("Data"); 或 utility::clearCache("Data-Logs"); class uti ...
- Murano Weekly Meeting 2016.05.24
Meeting time: 2016.May.24 1:00~2:00 Chairperson: Kirill Zaitsev, from Mirantis Meeting summary: 1.A ...
- Beam概念学习系列之PCollection数据集
不多说,直接上干货! PCollection数据集 PCollection是Apache Beam中数据的不可变集合,可以是有限的数据集合也可以是无限的数据集合. 有限数据集,这种一般对应的是批处理 ...