目录
10.14 2018-2019 ACM-ICPC, Asia Dhaka Regional Contest
C是数学题,H是个置换群,EJ签到,四个都不是我写的
不补这场了
B.Counting Inversion(数位DP)√
数位DP,过程中状压状态s表示前面几位每个数出现了多少次,便于枚举后面的位时统计逆序对数。
然后再求一下 当前位选一个数会有多少种方案,再乘以它产生的逆序对数。
还是比较easy的。数位DP复杂度果然难猜hhh 记忆化写了就能过。
注意进制至少是14(一个数最多出现13次)。
//2791ms 95900KB
#include <bits/stdc++.h>
#define BIT 14
#define gc() getchar()
typedef long long LL;
const int N=555;
int bit,A[N];
LL pw[N],B[N],pw10[N];
std::unordered_map<LL,LL> f[15],g[15];
inline LL read()
{
LL now=0,f=1; char c=gc();
for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now*f;
}
LL DFS(int bit,LL s,bool lim,bool lead)
{
if(!bit) return 0;
if(!lim && !lead && f[bit].count(s)) return f[bit][s];//lead:another map
else if(!lim && lead && g[bit].count(s)) return g[bit][s];
LL res=0,tmp=s; int mx=lim?A[bit]:9;
for(int i=0,now=0; i<=mx; ++i)
{
res+=DFS(bit-1,i?s+pw[i]:(lead?0:s+pw[i]),lim&&i==mx,lead&&!i)+1ll*now*(lim&&i==mx?B[bit-1]+1:pw10[bit-1]);
now+=tmp%14, tmp/=14;
}
if(!lim && !lead) f[bit][s]=res;
else if(!lim && lead) g[bit][s]=res;
return res;
}
LL Calc(LL x)
{
bit=0;
for(LL tmp=x; tmp; A[++bit]=tmp%10,tmp/=10);
for(int i=1; i<=bit; ++i) B[i]=A[i]*pw10[i-1]+B[i-1];
return DFS(bit,0,1,1);
}
int main()
{
pw[0]=pw10[0]=1;
for(int i=1; i<=15; ++i) pw[i]=pw[i-1]*14,pw10[i]=pw10[i-1]*10;
for(int TS=read(),Ts=1; Ts<=TS; ++Ts)
{
LL l=read(),r=read();
printf("Case %d: %lld
",Ts,Calc(r)-Calc(l-1));
}
return 0;
}
F.Path Intersection(树链剖分)√
树剖维护全局最大值及其个数即可。
可以剪剪枝以及注意Clear(不过n只有10000,logn很小)。
//421ms 5700KB
#include <bits/stdc++.h>
#define gc() getchar()
typedef long long LL;
const int N=2e4+5;
int n,Index,H[N],Enum,nxt[N<<1],to[N<<1],L[N],fa[N],dep[N],son[N],sz[N],top[N];
struct Segment_Tree
{
#define S N*18
int mx[S],sum[S],tag[S];
bool clear[S];
#undef S
#define ls rt<<1
#define rs rt<<1|1
#define lson l,m,ls
#define rson m+1,r,rs
inline void Update(int rt)
{
mx[rt]=std::max(mx[ls],mx[rs]);
if(mx[ls]<mx[rs]) sum[rt]=sum[rs];
else if(mx[ls]>mx[rs]) sum[rt]=sum[ls];
else sum[rt]=sum[ls]+sum[rs];
}
inline void Add(int rt,int v)
{
mx[rt]+=v, tag[rt]+=v;
}
inline void Clear(int rt,int m)
{
mx[rt]=0, tag[rt]=0, sum[rt]=m, clear[rt]=1;
}
inline void PushDown(int rt,int m)
{
if(clear[rt]) Clear(ls,m-(m>>1)), Clear(rs,m>>1), clear[rt]=0;
if(tag[rt]) Add(ls,tag[rt]), Add(rs,tag[rt]), tag[rt]=0;
}
void Build(int l,int r,int rt)
{
tag[rt]=mx[rt]=clear[rt]=0, sum[rt]=r-l+1;
if(l==r) return;
int m=l+r>>1;
Build(lson), Build(rson);
}
void Modify(int l,int r,int rt,int L,int R)
{
if(L<=l && r<=R) {Add(rt,1); return;}
PushDown(rt,r-l+1);
int m=l+r>>1;
if(L<=m) Modify(lson,L,R);
if(m<R) Modify(rson,L,R);
Update(rt);
}
void Clear(int l,int r,int rt,int L,int R)
{
if(L<=l && r<=R) {Clear(rt,r-l+1); return;}
PushDown(rt,r-l+1);
int m=l+r>>1;
if(L<=m) Clear(lson,L,R);
if(m<R) Clear(rson,L,R);
Update(rt);
}
}T;
inline int read()
{
int now=0,f=1; char c=gc();
for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now*f;
}
inline void AE(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
void DFS1(int x)
{
int mx=0; sz[x]=1, son[x]=0;
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa[x])
fa[v]=x, dep[v]=dep[x]+1, DFS1(v), sz[x]+=sz[v], sz[v]>mx&&(mx=sz[v],son[x]=v);
}
void DFS2(int x,int tp)
{
top[x]=tp, L[x]=++Index;
if(son[x])
{
DFS2(son[x],tp);
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa[x] && v!=son[x])
DFS2(v,v);
}
}
void Modify(int u,int v)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) std::swap(u,v);
T.Modify(1,n,1,L[top[u]],L[u]), u=fa[top[u]];
}
if(dep[u]>dep[v]) std::swap(u,v);
T.Modify(1,n,1,L[u],L[v]);
}
void Clear(int u,int v)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) std::swap(u,v);
T.Clear(1,n,1,L[top[u]],L[u]), u=fa[top[u]];
}
if(dep[u]>dep[v]) std::swap(u,v);
T.Clear(1,n,1,L[u],L[v]);
}
int main()
{
static int qa[100],qb[100];
for(int TS=read(),Ts=1; Ts<=TS; ++Ts)
{
printf("Case %d:
",Ts);
int n=read(); ::n=n;
for(int i=1; i<n; ++i) AE(read(),read());
fa[1]=0, dep[1]=1, DFS1(1), DFS2(1,1);
T.Build(1,n,1);
// for(int i=1; i<=n; ++i) printf("%d: L:%d fa:%d dep:%d son:%d top:%d
",i,L[i],fa[i],dep[i],son[i],top[i]);
int Q=read();
for(int i=1; i<=Q; ++i)
{
int k=read(),p=1;
for(int j=1; j<=k; ++j) qa[j]=read(), qb[j]=read();
for(p=1; p<=k&&T.mx[1]==p-1; ++p) Modify(qa[p],qb[p]);
// puts("Query:");
printf("%d
",T.mx[1]==k?T.sum[1]:0);
for(int j=1; j<p; ++j) Clear(qa[j],qb[j]);
}
Index=Enum=0, memset(H,0,n+2<<2);
}
return 0;
}/*
2
13
1 2 2 3 3 4 2 5 2 6
5 7 5 8 6 9 4 10 4 11 1 12 1 13
6
2 4 5 7 10
1 2 9
2 4 8 5 10
2 4 8 3 6
2 10 2 7 8
2 10 2 7 9
13
1 2 2 3 3 4 2 5 2 6
5 7 5 8 6 9 4 10 4 11 1 12 1 13
12
2 4 5 7 10
1 2 9
2 4 8 5 10
2 4 8 3 6
2 10 2 7 8
2 10 2 7 9
1 2 2
1 3 3
1 4 4
1 5 5
1 6 6
1 7 7
4
6 1 2 2 3 3 4 2 5 2 6
2 2 4 5 3 6
3 4 5 3 1 2 6
2 1 2
1
2 1 1 2 2
6 1 2 2 3 3 4 2 5 2 6
2 2 4 5 3 6
3 4 5 3 1 2 6
2 1 2
1
2 1 1 2 2
*/