T1
先将两个大数分开,很显然一个很小,一个是111....1
这样的形式
第一个直接暴力枚举,第二个考虑转化为(10^k-1)/9
这样的形式,然后求 9 的逆元,注意 9 对于 3 没有逆元,特判
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
long long ksm(long long a,long long b,long long p)
{
long long res=1;
while(b)
{
if(b&1) res=res*a%p;
b>>=1;
a=a*a%p;
}
return res;
}
string s;
long long ans,ap,p[5000010];
bool pr[5000010];
int cnt;
void init()
{
for(int i=2;i<=5000000;i++)
{
if(!pr[i])
{
p[++cnt]=i;
for(int j=2;i*j<=5000000;j++)
{
pr[i*j]=1;
}
}
}
}
long long work(long long len,long long p)
{
if(p==3) return len%3==0;
return (ksm(10,len,p)-1+p)%p*ksm(9,p-2,p)%p==0;
}
int main()
{
//freopen("candy.in","r",stdin);
//freopen("candy.out","r",stdout);
init();
cin>>s;
for(int i=0;i<s.size();i++) ans+=s[i]-'0';
ap=ans;
for(long long i=1;i<=cnt;i++)
{
if(ans%p[i]==0||work(s.size(),p[i]))
{
ap=p[i];
break;
}
}
printf("%lld",ap);
}
T2
大力dp,设dp[i][j][k]表示[i,j]对于k这个边界是否可行
没有打过的原因是打了一个假的n^2实际n^4的记忆化,看过主定理发现并不是我所想的复杂度
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
int a[1010];
bool con[1010][1010];
bool f[510][510][510];
bool vis[510][510][510];
int n;
int gcd(int a,int b)
{
while((a%=b)&&(b%=a));
return a+b;
}
bool dfs(int l,int r,int now)
{
if(vis[l][r][now]) return f[l][r][now];
vis[l][r][now]=1;
if(l>r) return f[l][r][now]=1;
if(l==r) return f[l][r][now]=con[l][now];
for(int i=l;i<=r;i++)
if(con[i][now]&&dfs(l,i-1,i)&&dfs(i+1,r,i))
return f[l][r][now]=1;
return f[l][r][now]=0;
}
void work()
{
memset(con,0,sizeof(con));
memset(vis,0,sizeof(vis));
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(gcd(a[i],a[j])!=1)
con[i][j]=1;
// for(int i=1;i<=n;i++)
// {
// for(int j=1;j<=n;j++)
// printf("%d ",con[i][j]);
// printf("
");
// }
bool flag=0;
for(int i=1;i<=n;i++) if(dfs(1,i-1,i)&&dfs(i+1,n,i))
{
printf("Yes
");
return ;
}
printf("No
");
}
int main()
{
//freopen("tree.in","r",stdin);
//freopen("tree.out","r",stdout);
int t;
scanf("%d",&t);
while(t--)
{
memset(a,0,sizeof(a));
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
work();
}
}
T3
LNOI原题
没a的原因是线段树在上传的时候没有更新(好像之前也出现过,这种东西还很难调,没有啥明确的可以指出是这个错误的
直接考虑前缀化询问,然后离线就行
#include <cstdio>
#include <algorithm>
using namespace std;
struct Segment
{
long long val,tag;
}tree[500010<<2];
struct Edge
{
int to,next;
}e[1000010];
struct Query
{
int pos,id,pi;
long long vf;
}wq[1000010];
int n,q;
int num,head[1000010];
int size[500010],fa[500010],son[500010],top[500010],p[500010],cnt,cnting;
long long ans[500010];
bool cmp(Query a,Query b)
{
return a.pos<b.pos;
}
void addedge(int a,int b)
{
e[++num].to=b;
e[num].next=head[a];
head[a]=num;
}
void pushdown(int u,int l,int r)
{
int mid=(l+r)>>1;
tree[u<<1].tag+=tree[u].tag;
tree[u<<1|1].tag+=tree[u].tag;
tree[u<<1].val+=(long long)(mid-l+1)*tree[u].tag%201314;
tree[u<<1|1].val+=(long long)(r-mid)*tree[u].tag%201314;
tree[u].tag=0;
}
long long findtree(int u,int l,int r,int x,int y)
{
if(x<=l&&r<=y) return tree[u].val;
if(tree[u].tag) pushdown(u,l,r);
int mid=(l+r)>>1;
long long ans=0;
if(x<=mid) ans+=findtree(u<<1,l,mid,x,y);
if(y>mid) ans+=findtree(u<<1|1,mid+1,r,x,y);
return ans%201314;
}
void changetree(int u,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
{
tree[u].val+=(r-l+1);
tree[u].val%=201314;
tree[u].tag++;
tree[u].tag%=201314;
return ;
}
if(tree[u].tag) pushdown(u,l,r);
int mid=(l+r)>>1;
if(x<=mid) changetree(u<<1,l,mid,x,y);
if(y>mid) changetree(u<<1|1,mid+1,r,x,y);
tree[u].val=(tree[u<<1].val+tree[u<<1|1].val)%201314;
}
void dfs1(int u)
{
size[u]=1;
for(int i=head[u];i;i=e[i].next)
{
fa[e[i].to]=u;
dfs1(e[i].to);
size[u]+=size[e[i].to];
if(size[e[i].to]>size[son[u]]) son[u]=e[i].to;
}
}
void dfs2(int u,int t)
{
top[u]=t;
p[u]=++cnting;
if(!son[u]) return ;
dfs2(son[u],t);
for(int i=head[u];i;i=e[i].next)
{
if(e[i].to^son[u])
{
dfs2(e[i].to,e[i].to);
}
}
}
void change(int u)
{
while(u)
{
changetree(1,1,n,p[top[u]],p[u]);
u=fa[top[u]];
}
}
int query(int u)
{
long long res=0;
while(u)
{
res+=findtree(1,1,n,p[top[u]],p[u]);
res%=201314;
u=fa[top[u]];
}
return res;
}
int main()
{
//freopen("elf.in","r",stdin);
//freopen("elf.out","r",stdout);
scanf("%d%d",&n,&q);
for(int i=2;i<=n;i++)
{
int x;
scanf("%d",&x);
addedge(x,i);
}
for(int i=1;i<=q;i++)
{
int l,r,z;
scanf("%d%d%d",&l,&r,&z);
wq[++cnt].id=i;
wq[cnt].pi=z;
wq[cnt].pos=l-1;
wq[cnt].vf=-1;
wq[++cnt].id=i;
wq[cnt].pi=z;
wq[cnt].pos=r;
wq[cnt].vf=1;
}
dfs1(1);
dfs2(1,1);
fa[1]=0;
sort(wq+1,wq+cnt+1,cmp);
int pl=1;
while(wq[pl].pos==0&&pl<=cnt) pl++;
for(int i=1;i<=n;i++)
{
change(i);
while(wq[pl].pos==i&&pl<=cnt)
{
ans[wq[pl].id]+=wq[pl].vf*query(wq[pl].pi);
ans[wq[pl].id]=((ans[wq[pl].id]%201314)+201314)%201314;
pl++;
}
}
for(int i=1;i<=q;i++) printf("%lld
",ans[i]);
}