2018-2019 ACM-ICPC, Asia Dhaka Regional Contest (B,F)


10.14 2018-2019 ACM-ICPC, Asia Dhaka Regional Contest

CF

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
*/

原文地址:https://www.cnblogs.com/SovietPower/p/13818053.html