【2019.9.15】
2019.9.15
summary
- 时间安排不合理 大部分时间用在1、2题 第三题啥都没打成
- 低级错误 空间开小了 而且最开始打的时候我都没有测第四组样例?!最后十几分钟发现第四组样例没过==
- 基础不牢 加分二叉树这题我都没做过 gg
- 浮躁
Candy
糖糖有一个整数A,设A的十进制表示为 \(a_1a_2a_3...a_n\);
定义 \(rotate(a_1a_2a_3...a_n)=a_2a_3...a_na_1\)
糖糖利用这个方法生成了n个数字串,其中:
\(b1=a,b2=rotate(b1),...,b_n=rotate(b_{n-1})\)
糖糖对于这些数字串在十进制下的和很感兴趣,现设 \(\sum{b_i}=S\)
她想知道S的最小非1的因子是多少
首先肯定先找下规律看看有没有规律,但是没用的.
不难发现最终的和的形式是\(sum\_digit(111111....1)\)的形式,其中\(sum\_digit\)表示所有数位的和.
所以无非答案就是\(sum\_digit\)的最小质因子或者是\(11111111..1\)的最小质因子
若最终答案不在\(sum\_digit\)里面的话呢,假设\(sum\_digit\)的最小质因子为\(x\)那么也就是说\(1111111...1\)里面存在一个质因子\(y\),\(y<x\)并且\(1111111...1\%y==0\)
考虑\(1111111...1=(10^n-1)/9\)(n表示有多少个1)
那么问题就转化成了\((10^n-1)/9%y==0\),我们可以枚举这个\(y\).因为和最大也就\(5e6\),所以\(y\)最多也不会超过\(5e6\),用线性筛预处理一下即可
==我搞那个b=qpow(10ll,n,(ll)prim[i]*9)
要模\(prim[i]*9\)推了好久
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=500000+10,M=5e6+50,inf=0x3f3f3f3f;
int n,sum;char a[N];
int v[M],prim[N],cnt=0;
void Prime(int m){
for(int i=2;i<=m;i++){
if(!v[i]) v[i]=i,prim[++cnt]=i;
for(int j=1;j<=cnt&&prim[j]<=m/i;j++){
v[i*prim[j]]=prim[j];
if(!i%prim[j]) break;
}
}
}
ll qpow(ll a,int b,ll P){
ll ret=1ll;
while(b){
if(b&1) ret=(ret*a)%P;
a=(a*a)%P,b>>=1;
}
return ret;
}
int main(){
//freopen("candy.in","r",stdin);
// freopen("candy.out","w",stdout);
Prime(4500000);
//printf("%d\n",cnt);
//printf("%d %d",v[11111],v[111111]);
while(scanf("%s",a+1)!=EOF){
n=strlen(a+1),sum=0;
for(int i=1;i<=n;++i) sum+=(a[i]-'0');
int ans=v[sum];
ll b;
for(int i=1;i<=cnt&&prim[i]<(sum==1?inf:ans);++i){
b=qpow(10ll,n,(ll)prim[i]*9);//
b=(b-1)/9;
if(!b%prim[i]){ans=prim[i];break;}
}
printf("%d\n",ans);
}
return 0;
}
遗失的二叉树
小T很喜欢研究树形数据结构,这一天,他的哥哥小Q丢给了小T一个问题:给定一序列,判断其是否为一颗二叉树的中序遍历,对于小T来说,这个问题太简单了,所以哥哥又添加了一个条件:树边连接的两个点的权值不能互质。现在小T对这个问题毫无对策,于是他请你帮他解决这个问题。
Tree’s Solution
考虑区间\(dp\),\(L[l][r]\)表示区间\([l,r]\) 是否可以作为r的左儿子,即\(L[l][r]\)表示以r为根 [l,r-1]为左子树是否合法,\(R[l][r]\)表示区间\([l,r]\)是否可以作为l的右儿子,即\(R[l][r]\)表示以\(l\)为根\([l+1,r]\)为右子树是否合法, 枚举\(k\)与根节点进行转移,那么就可以得到方程:
\(L[l][r] |= L[l][k]\& R[k][r-1]\&mp[k][r]\);
\(R[l][r] |= L[l+1][k]\&R[k][r]\&mp[k][l];\)
最后判断一下存不存在一个\(i\)使得\((L[1][i]\&R[i][n])==1\)即可
==看到中序遍历然后就放弃 刚另外两道题用了太多时间 最后这题只剩差不多半个小时四十分钟的亚子
#include<bits/stdc++.h>
using namespace std;
const int N=500+10,M=1e5+50,inf=0x3f3f3f3f;
int n,ok,a[N],b[N][N],L[N][N],R[N][N];
template <class t>void rd(t &x){
x=0;int w=0;char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x=w?-x:x;
}
int gcd(int x,int y){return !y?x:gcd(y,x%y);}
int main(){
freopen("T1.txt","r",stdin);
//freopen("and.out","w",stdout);
int T;rd(T);
while(T--){
rd(n);ok=0;
memset(b,0,sizeof(b));
memset(L,0,sizeof(L));
memset(R,0,sizeof(R));
for(int i=1;i<=n;++i) rd(a[i]),L[i][i]=R[i][i]=b[i][i]=1;
for(int i=1;i<=n;++i)
for(int j=i+1;j<=n;++j) b[i][j]=b[j][i]=(gcd(a[i],a[j])!=1);
for(int len=2;len<=n;++len)
for(int i=1,j;(j=i+len-1)<=n;++i)
for(int k=i;k<=j&&(!L[i][j]||!R[i][j]);++k)
L[i][j]|=(L[i][k]&R[k][j-1]&b[k][j]),
R[i][j]|=(L[i+1][k]&R[k][j]&b[k][i]);
for(int i=1;i<=n&&!ok;++i) if(L[1][i]&R[i][n]) ok=1;
if(ok) puts("Yes");
else puts("No");
}
return 0;
}
精灵
wonderland的地图可以抽象成一个N个点的有根树,第i个点上生活着编号为i的精灵,根节点为1号节点。
一个点的深度定义为这个节点到根的距离+1,第i只精灵和第j只精灵的亲密度为他们在树上最近公共祖先的深度。
现在Jessica想询问你Q次,每次询问第z只精灵和第l~r只精灵的亲密度的和是多少。答案对201314(不是一个质数)取模。
看完题 75分很稳
然后想好了暴力的思路 准备去看第二题 看着中序遍历我还是滚了...
在草稿本上捯饬了半天 我居然想出了正解
对不起我询问开的一倍空间我这就滚 30
100昏
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls (o<<1)
#define rs (o<<1|1)
const int N=1e5+10,M=1e5+50,inf=0x3f3f3f3f,P=201314;
int n,m;ll ans[N];
struct quer{
int id,pos,k,x;
bool operator <(const quer&X)const{return pos<X.pos;}
}q[N<<1];
template <class t>void rd(t &x){
x=0;int w=0;char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x=w?-x:x;
}
int head[N],tot=0;
struct edge{int v,nxt;}e[N];
void add(int u,int v){
e[++tot]=(edge){v,head[u]},head[u]=tot;
}
int idx=0,dfn[N],f[N],son[N],sz[N],dep[N],top[N];
void dfs1(int u,int fa){
dep[u]=dep[fa]+1,sz[u]=1;
for(int i=head[u],v,mxs=-1;i;i=e[i].nxt){
dfs1((v=e[i].v),u),sz[u]+=sz[v];
if(sz[v]>mxs) son[u]=v,mxs=sz[v];
}
}
void dfs2(int u,int topf){
dfn[u]=++idx,top[u]=topf;
if(!son[u]) return;
dfs2(son[u],topf);
for(int i=head[u],v;i;i=e[i].nxt)
if((v=e[i].v)!=son[u]) dfs2(v,v);
}
struct node{ll val,tg;}t[N<<2];
void pup(int o){t[o].val=t[ls].val+t[rs].val;}
void updnode(int o,int l,int r,ll k){t[o].val+=(r-l+1)*k,t[o].tg+=k;}
void pudw(int o,int l,int r){
if(!t[o].tg) return;
int mid=l+r>>1;
updnode(ls,l,mid,t[o].tg),updnode(rs,mid+1,r,t[o].tg),t[o].tg=0;
}
void upd(int o,int l,int r,int x,int y,ll k){
if(l>y||r<x) return;
if(x<=l&&r<=y){updnode(o,l,r,k);return;}
pudw(o,l,r);
int mid=l+r>>1;
upd(ls,l,mid,x,y,k),upd(rs,mid+1,r,x,y,k);
pup(o);
}
ll query(int o,int l,int r,int x,int y){
if(l>y||r<x) return 0;
if(x<=l&&r<=y) return t[o].val;
pudw(o,l,r);
int mid=l+r>>1;ll ans;
ans=query(ls,l,mid,x,y)+query(rs,mid+1,r,x,y);
pup(o);
return ans;
}
void updrange(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
upd(1,1,n,dfn[top[x]],dfn[x],1);
x=f[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
upd(1,1,n,dep[x],dep[y],1);
}
ll qrange(int x,int y){
ll sum=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
sum+=query(1,1,n,dfn[top[x]],dfn[x]);
x=f[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
sum+=query(1,1,n,dep[x],dep[y]);
return sum;
}
int main(){
freopen("T1.txt","r",stdin);
// freopen("elf.out","w",stdout);
rd(n),rd(m);
for(int i=2,x;i<=n;++i) rd(f[i]),add(++f[i],i);
dfs1(1,0),dfs2(1,1);
int x,l,r,C=0;
for(int i=1;i<=m;++i){
rd(l),rd(r),rd(x);
q[++C]=(quer){i,++l-1,-1,++x},q[++C]=(quer){i,++r,1,x};
}
sort(q+1,q+C+1);
for(int i=1,j=0,pos,id;i<=C;++i){
id=q[i].id,pos=q[i].pos,x=q[i].x;
while(j<n&&j<pos) updrange(1,++j);
ans[id]=(ans[id]+q[i].k*qrange(1,x))%P;
}
for(int i=1;i<=m;++i) printf("%lld\n",((ll)ans[i]+P)%(1ll*P));
return 0;
}