游记DAY2"/>
海亮游记DAY2
今天是在海亮的第二天,期间又被各路大神按在地上摩擦(还是我太弱了)
按照惯例,今天还是早上考试QWQ(内心绝望)
在昨天考试题成绩的反映下,老师成功的被迫改题,使得今天的题变得友好一些(没错!是友好一些)
题目:
1.小刚传说
(legendary.cpp)
【时空限制】
时间限制:2s
空间限制:256MB
【问题描述】
众所周知,刘小刚是海亮中学的金牌教练,然而世人并不知道他的传奇经历,以及那个曾经轰动世界的名字sharpland。
2003年,美国研究团队在量子计算机的研制上取得了重大突破,一旦美国成功研发出量子计算机,一切加密手段都将形同虚设。当此之时,国内第一黑客sharpland秘密潜入美国中央情报局,得知关于量子计算机的研究成果封存于五角大楼计算机群之中。经过一周的0Day挖掘,sharpland成功侵入计算机群,却发现这里的文件保护机制非同寻常。
五角大楼计算机群的文件形成了树结构,且树的形态随时间变化。已知初始时刻树上仅有一个根节点1,当成功拷贝结点i上的文件时,树上会新增结点i+1,它的父亲为一个已存在的结点。树的大小增加为n时便会停止。
sharpland通过之前挖掘的0Day成功推算出了所有新增结点的父亲,为了破解文件保护系统,他需要在每次新增结点后新增的结点i和上一次新增的结点i-1的路径长度。
【输入格式】
第一行,一个整数n表示最终树的大小。
接下来n-1行,每行一个整数表示新增节点的父亲。
【输出格式】
共n-1行,每行一个整数表示答案。
【输入输出样例1】
legendary.in | legendary.out |
6 1 2 2 1 5 | 1 1 2 3 1
|
【输入输出样例2】
legendary.in | legendary.out |
10 1 1 3 1 2 3 6 1 8 | 1 2 1 3 3 4 5 4 5
|
【数据范围】
对于30%的数据,
对于60%的数据,
对于100%的数据,
【后记】
sharpland成功窃取数据的那一刻,中央情报局察觉到了数据失窃并发布全球通缉令,sharpland隐姓埋名逃会国内,以刘小刚为化名,以高中竞赛教练为掩护,生活至今。然而第一黑客sharpland之名早已响彻世界。
2.中珂院的难题
(kotori.cpp)
【时空限制】
时间限制:2s
空间限制:256MB
【问题描述】
“我已经无法获得幸福了,因为我发觉,我早已是幸福的人了。”——珂朵莉
近日,中国珂学院的研究员们遇到了一个难题,他们手上有一个数列,现在有m次操作,每次操作有三个参数,表示选取一个区间[l,r],对于区间中的每个元素把它加上一个组合数,求m次操作后得到的数列,答案对取模。
“要是我们中有OI选手在就好了”一位研究员如是说,于是他们找到了身为OI选手的你,希望你能帮助他们解决这个问题。
【输入格式】
第一行,两个整数n,m。
接下来m行,每行3个整数l,r,k表示一次操作。
【输出格式】
一行n个整数表示操作结束后的数列,答案对取模。
【输入输出样例1】
kotori.in | kotori.out |
5 1 0 0 0 0 0 1 5 0 | 1 1 1 1 1 |
【输入输出样例2】
kotori.in | kotori.out |
10 2 1 2 3 4 5 0 0 0 0 0 1 6 1 6 10 2 | 2 4 6 8 10 7 3 6 10 15 |
【数据范围】
对于50%的数据,
对于100%的数据,
3.欧拉图
(euler.cpp)
【时空限制】
时间限制:2s
空间限制:512MB
【问题描述】
递推树上递推果,递推树下你和我。递推树前做游戏,递推树后做交易。
欧拉图指的是拥有欧拉回路的图,也就是说一个图是欧拉图需要满足图是连通的,且所有点的度数为偶数。图中不能有重边和自环。
求n个点的有标号欧拉图有多少个,两个欧拉图不同,当且仅当存在边集不同。
答案对998244353取模。
【输入格式】
一个整数n。
【输出格式】
一个整数表示答案,答案对998244353取模。
【输入输出样例1】
euler.in | euler.out |
5 | 38 |
【输入输出样例2】
euler.in | euler.out |
506 | 46050276 |
【数据范围】
对于20% 的数据, n≤10
对于60% 的数据, n≤2000
对于100% 的数据, n≤100000
数据纯手工构造,有梯度
T1:
这道题是一道十分裸的lca,使用倍增lca即可分分钟切掉
当然,也不免有大佬会使用其他方法爆切这道题。
1 #include<bits/stdc++.h> 2 using namespace std; 3 template <typename type> 4 void scan(type &x){ 5 type f=1;x=0;char s=getchar(); 6 while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} 7 while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} 8 x*=f; 9 } 10 #define maxn 200007 11 //struct node{ 12 // int now,to,next; 13 //}e[400007]; 14 int /*head[maxn],*/fa[30][maxn],cnt,n,dep[maxn],t; 15 16 int lca(int u,int v){ 17 if(dep[u]>dep[v])swap(u,v); 18 for(int i=0,d=dep[v]-dep[u];d;d>>=1,i++){ 19 if(d&1)v=fa[i][v]; 20 } 21 if(u==v)return u; 22 for(int i=t;i>=0;i--){ 23 if(fa[i][v]!=fa[i][u]){ 24 v=fa[i][v]; 25 u=fa[i][u]; 26 } 27 } 28 return fa[0][u]; 29 } 30 31 32 33 int main(){ 34 freopen("legendary.in","r",stdin); 35 freopen("legendary.out","w",stdout); 36 scan(n); 37 t=log(n)/log(2); 38 dep[1]=0; 39 fa[0][1]=-1; 40 for(int i=2;i<=n;i++){ 41 int a; 42 scan(a); 43 fa[0][i]=a; 44 dep[i]=dep[a]+1; 45 // if(i==1){ 46 // printf("1\n"); 47 // continue; 48 // } 49 // printf("lca :%d\n",lca(i,i-1)); 50 // printf("%d %d %d\n",dep[i],dep[i-1],dep[lca(i,i-1)]); 51 52 } 53 for(int i=1;1<<i<n;i++){ 54 for(int j=1;j<=n;j++){ 55 if(fa[i-1][j]<0)fa[i][j]=-1; 56 else fa[i][j]=fa[i-1][fa[i-1][j]]; 57 } 58 } 59 for(int i=2;i<=n;i++){ 60 printf("%d\n",dep[i]+dep[i-1]-2*dep[lca(i,i-1)]); 61 } 62 63 return 0; 64 }T1
T2:
这是一道多阶差分的问题。
当然,我拿到这道题的时候肯定是没有看出正解来的QWQ
所以,我就去想拿到50分的暴力
具体就是预处理一下组合数,然后直接进行计算。
1 #include<bits/stdc++.h> 2 using namespace std; 3 template <typename type> 4 void scan(type &x){ 5 type f=1;x=0;char s=getchar(); 6 while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} 7 while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} 8 x*=f; 9 } 10 #define ll long long 11 //#define itn int 12 const int mod=1e9+7; 13 ll a[100107],s[100107][107],c[107][100007]; 14 int n,m; 15 int main(){ 16 freopen("kotori.in","r",stdin); 17 freopen("kotori.out","w",stdout); 18 scan(n); 19 scan(m); 20 for(int i=1;i<=n;i++){ 21 scan(a[i]); 22 a[i]%=mod; 23 } 24 for(int i=0;i<=8006;i++)b[i][i]=1,b[0][i]=1; 25 for(int i=1;i<=8006;i++){ 26 for(int j=i+1;j<=8006;j++){ 27 b[i][j]=(b[i-1][j-1]+b[i][j-1])%mod; 28 } 29 } 30 while(m--){ 31 int l,r,k; 32 scan(l); 33 scan(r); 34 scan(k); 35 for(int i=l;i<=r;i++){ 36 a[i]=(a[i]+b[k][i-l+k])%mod; 37 } 38 } 39 for(int i=1;i<=n;i++) 40 printf("%d ",a[i]%mod); 41 return 0; 42 }T2 50分
然后正解的话。。。
其实是一个多阶差分的问题
嗯,偷个懒,粘了过来^_^
1 #include<bits/stdc++.h> 2 #define FILE "kotori" 3 #define MAXN 100010 4 #define cadd(a,b) a=add(a,b) 5 #define csub(a,b) a=sub(a,b) 6 using namespace std; 7 const int mod=1e9+7; 8 int n,m,a[MAXN],fac[MAXN<<1],inv[MAXN<<1],s[105][MAXN]; 9 inline int read(){ 10 int x=0,f=1; char ch=getchar(); 11 while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch=getchar();} 12 while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} 13 return x*f; 14 } 15 inline int add(int a,int b){return (a+=b)>=mod?a-mod:a;} 16 inline int sub(int a,int b){return (a-=b)<0?a+mod:a;} 17 inline int mul(int a,int b){return 1LL*a*b%mod;} 18 inline int Pow(int a,int b){ 19 int ret=1; 20 while(b){ 21 if(b&1) ret=mul(ret,a); 22 b>>=1; a=mul(a,a); 23 }return ret; 24 } 25 inline int C(int a,int b){ 26 return mul(fac[a],mul(inv[b],inv[a-b])); 27 } 28 int main(){ 29 freopen(FILE".in","r",stdin); 30 freopen(FILE".out","w",stdout); 31 n=read(); m=read(); int N=200000; fac[0]=1; 32 for(int i=1;i<=n;++i) a[i]=read(); 33 for(int i=1;i<=N;++i) fac[i]=mul(fac[i-1],i); inv[N]=Pow(fac[N],mod-2); 34 for(int i=N-1;i>=0;--i) inv[i]=mul(inv[i+1],i+1); 35 for(int i=1;i<=m;++i){ 36 int l=read(),r=read(),K=read(); 37 cadd(s[K+1][l],1); 38 for(int k=1;k<=K+1;++k) 39 csub(s[k][r+1],C(K+1-k+r-l,K+1-k)); 40 } 41 for(int k=100;k>=0;--k){ 42 int cnt=0; 43 for(int i=1;i<=n;++i){ 44 cadd(cnt,s[k+1][i]); 45 cadd(s[k][i],cnt); 46 } 47 } 48 for(int i=1;i<=n;++i)printf("%d ",add(a[i],s[0][i])); 49 return 0; 50 }正解
T3:
t3的话,我是真的还不会QWQ,有时间再看!!!
先把题解贴上吧。
1 #include<bits/stdc++.h> 2 #define FILE "euler" 3 #define MAXN 600100 4 using namespace std; 5 const int mod(998244353),G(3); 6 int n,a[MAXN],b[MAXN],temp[MAXN],inva[MAXN],R[MAXN],da[MAXN],w[MAXN],inv[MAXN],fac[MAXN],wn[2][20]; 7 inline int read(){ 8 int x=0,f=1; char ch=getchar(); 9 while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch=getchar();} 10 while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} 11 return x*f; 12 } 13 inline int add(int a,int b){return (a+=b)>=mod?a-mod:a;} 14 inline int sub(int a,int b){return (a-=b)<0?a+mod:a;} 15 inline int mul(int a,int b){return 1LL*a*b%mod;} 16 inline int fast(int a,long long b){int ret(1);for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;} 17 void pre(){ 18 w[0]=1; 19 wn[0][18]=fast(G,(mod-1)/(1<<18)); 20 wn[1][18]=fast(wn[0][18],mod-2); 21 for(int i=17;i>=0;--i)for(int k=0;k<=1;++k)wn[k][i]=mul(wn[k][i+1],wn[k][i+1]); 22 } 23 void NTT(int *a,int H,int f=0){ 24 int L=(1<<H); 25 for(int i=0;i<L;++i) if(i<(R[i]=(R[i>>1]>>1)|((i&1)<<(H-1)))) swap(a[i],a[R[i]]); 26 for(int e=1;e<=H;++e){ 27 int len=(1<<e),l=(len>>1); 28 for(int i=1;i<l;++i) w[i]=mul(w[i-1],wn[f][e]); 29 for(int st=0;st<L;st+=len)for(int k=0;k<l;++k){ 30 int x=a[st+k],y=mul(w[k],a[st+k+l]); 31 a[st+k]=add(x,y); a[st+k+l]=sub(x,y); 32 } 33 } 34 if(f) for(int i=0,temp=fast(L,mod-2);i<L;++i) a[i]=mul(a[i],temp); 35 } 36 void getinv(int *a,int L,int *b){ 37 b[0]=fast(a[0],mod-2); 38 for(int now=0;(1<<now)<L;++now){ 39 int l=(1<<(now+1)); 40 for(int i=0;i<l;++i) temp[i]=a[i]; 41 for(int i=l;i<(l<<1);++i) temp[i]=0; 42 NTT(temp,now+2); NTT(b,now+2); 43 for(int i=0;i<(l<<1);++i) b[i]=mul(b[i],sub(2,mul(temp[i],b[i]))); 44 NTT(b,now+2,1); 45 for(int i=l;i<(l<<1);++i) b[i]=0; 46 } 47 for(int i=L;i<(L<<1);++i) b[i]=0; 48 } 49 void getIn(int *a,int H,int *b){ 50 int L=(1<<H); getinv(a,L,inva); 51 for(int i=0;i<L;++i) da[i]=mul(a[i+1],i+1); 52 NTT(inva,H); NTT(da,H); 53 for(int i=0;i<L;++i) temp[i]=mul(inva[i],da[i]); 54 NTT(temp,H,1); 55 for(int i=1;i<L;++i) b[i]=mul(temp[i-1],fast(i,mod-2)); 56 } 57 int main(){ 58 freopen(FILE".in","r",stdin); 59 freopen(FILE".out","w",stdout); 60 n=read(); pre(); 61 int L=1,H=0; while(L<=n) L<<=1,++H; 62 fac[0]=1; for(int i=1;i<=L;++i) fac[i]=mul(fac[i-1],i); 63 inv[L]=fast(fac[L],mod-2); 64 for(int i=L-1;i>=0;--i) inv[i]=mul(inv[i+1],i+1); 65 for(int i=1;i<=n;++i) a[i]=mul(fast(2,(long long)(i-2)*(i-1)/2),inv[i]); 66 a[0]=1; getIn(a,H,b); 67 int ans=mul(b[n],fac[n]); 68 printf("%d\n",ans); 69 return 0; 70 }std
好了,先到这吧,被题虐了一天,先回去自闭了。。。
转载于:.html
更多推荐
海亮游记DAY2
发布评论