# 【CodeChef】August Challenge 2019 Div2 解题报告

### $T1$：Football（点此看题面）

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 150
#define Gmax(x,y) (x<(y)&&(x=(y)))
using namespace std;
int n,a[N+5],b[N+5];
int main()
{
RI Tt,i,x,y,ans;scanf("%d",&Tt);W(Tt--)
{
for(scanf("%d",&n),ans=0,i=1;i<=n;++i) scanf("%d",a+i);
for(i=1;i<=n;++i) scanf("%d",b+i),Gmax(ans,20*a[i]-10*b[i]);//统计答案
printf("%d\n",ans);
}return 0;
}


### $T2$：Distribute Apples（点此看题面）

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 150
#define Gmax(x,y) (x<(y)&&(x=(y)))
using namespace std;
long long n,k;
int main()
{
RI Tt,i,x,y,ans;scanf("%d",&Tt);W(Tt--)
scanf("%lld%lld",&n,&k),puts((n%k||(n/k)%k)?"YES":"NO");//判断k|(n/k)
return 0;
}


### $T3$：Dilemma （点此看题面）

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define Gmax(x,y) (x<(y)&&(x=(y)))
using namespace std;
int n;char s[N+5];
int main()
{
RI Tt,i,t=0,res=0;scanf("%d",&Tt);W(Tt--)
{
for(scanf("%s",s),n=strlen(s),t=res=i=0;i^n;++i)
s[i]&1?(t^=1):(res^=t,t=0);puts(res^t?"WIN":"LOSE");//t统计当前连续1序列的奇偶性，res统计长度为奇数的连续1的序列的个数的奇偶性
}return 0;
}


### $T4$：Zombie and the Caves（点此看题面）

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
using namespace std;
int n,s[N+5],p[N+5];
class FastIO
{
private:
#define FS 100000
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
}F;
int main()
{
{
for(i=1;i<=n;++i) (s[i]+=s[i-1])<=n&&++p[s[i]];//求出序列并存入桶中
}return 0;
}


### $T5$：Guddu and his Mother（点此看题面）

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define LL long long
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
using namespace std;
int n,s[N+5];map<int,LL> p,g;
class FastIO
{
private:
#define FS 100000
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
}F;
int main()
{
{
ans=0,p.clear(),g.clear(),p[0]=0,g[0]=1;//清空
s[i]=s[i-1]^x,ans+=1LL*g[s[i]]*(i-1)-p[s[i]],p[s[i]]+=i,++g[s[i]];//统计前缀和，更新答案，更新map
printf("%lld\n",ans);//输出答案
}return 0;
}


### $T6$：Encoding（点此看题面）

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define X 1000000007
#define Inc(x,y) ((x+=(y))>=X&&(x-=X))
using namespace std;
int nl,nr;char L[N+5],R[N+5];
class DigitalDP
{
private:
#define Pr pair<int,int>
#define mp make_pair
#define fir first
#define sec second
int v[N+5],tn[N+5],f[N+5][10],g[N+5][10];
I Pr DP(CI x,CI lst,CI p)//数位DP
{
RI i,lim=p?v[x]:9;Pr t,k=mp(0,0);
if(!x) return mp(0,1);if(!p&&~f[x][lst]) return mp(f[x][lst],g[x][lst]);//若求过答案，直接返回
for(i=0;i<=lim;++i) t=DP(x-1,i,p&&(i==lim)),//枚举这一位填的数，处理后继状态
Inc(k.fir,t.fir),Inc(k.sec,t.sec),i^lst&&(k.fir=(1LL*tn[x]*i%X*t.sec+k.fir)%X);//统计答案和情况数
return f[x][lst]=k.fir,g[x][lst]=k.sec,k;//记忆化，返回答案
}
public:
I DigitalDP() {RI i;for(tn[1]=1,i=2;i<=N;++i) tn[i]=10LL*tn[i-1]%X;}//初始化10的幂
I int GetAns(CI x,char *s)
{
RI i,ans=0;Pr t;for(i=x;i;--i) v[i]=s[x-i]&15;memset(f,-1,sizeof(f));//清空
for(i=0;i<=v[x];++i) t=DP(x-1,i,i==v[x]),ans=(1LL*tn[x]*i%X*t.sec+t.fir+ans)%X;//枚举最高位，这个写法有点蠢啊
return ans;
}
}D;
int main()
{
RI Tt,p;scanf("%d",&Tt);W(Tt--)
{
scanf("%d%s%d%s",&nl,L,&nr,R);p=nl-1;W(L[p]=='0') L[p--]='9';--L[p];//将L-1差分
printf("%d\n",(D.GetAns(nr,R)-D.GetAns(nl,L)+X)%X);//求答案
}return 0;
}


### $T7$：Chef and Gordon Ramsay（点此看题面）

• 若$y$相对排名为$1$，求出子树内大于$y$的数的个数乘子树外大于$y$的数的个数（子树外的可以差分），并枚举子节点加上该儿子的子树内大于$y$的数的个数乘其他儿子子树内大于$y$的数的个数（其他儿子的可以差分）除以$2$。
• 若$y$相对排名为$2$，求出子树内大于$y$的数的个数乘子树外小于$y$的数的个数加上求出子树内小于$y$的数的个数乘子树外大于$y$的数的个数，并枚举子节点加上该儿子的子树内小于$y$的数的个数乘其他儿子子树内大于$y$的数的个数。
• 若$y$相对排名为$3$，与相对排名为$1$类似，略。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define LN 20
#define LL long long
using namespace std;
int n,ee,lnk[N+5],Sz[N+5],p[4];LL ans;struct edge {int to,nxt;}e[N<<1];
class FastIO
{
private:
#define FS 100000
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
}F;
template<int SZ,int PS> class SegmentTree//线段树
{
private:
#define LT l,mid,O[rt].S[0]
#define RT mid+1,r,O[rt].S[1]
#define PU(x) (O[x].V=O[O[x].S[0]].V+O[O[x].S[1]].V)
int n,Nt,Rt[SZ+5];struct node {int V,S[2];}O[PS+5];
I void Ins(CI v,CI l,CI r,int& rt)//单点修改
{
if(!rt&&(rt=++Nt,O[rt].S[0]=O[rt].S[1]=0),l==r) return (void)(O[rt].V=1);
RI mid=l+r>>1;v<=mid?Ins(v,LT):Ins(v,RT),PU(rt);
}
I int Qry(CI x,CI y,CI l,CI r,CI rt)//区间求和
{
if(!rt) return 0;if(x<=l&&r<=y) return O[rt].V;RI mid=l+r>>1;
return (x<=mid?Qry(x,y,LT):0)+(y>mid?Qry(x,y,RT):0);
}
I int Merge(CI l,CI r,CI x,CI y)//线段树合并
{
if(!x||!y) return x+y;RI rt=++Nt;if(l==r) return (O[rt].V=O[x].V+O[y].V);RI mid=l+r>>1;
O[rt].S[0]=Merge(l,mid,O[x].S[0],O[y].S[0]),O[rt].S[1]=Merge(mid+1,r,O[x].S[1],O[y].S[1]);
return PU(rt),rt;
}
public:
I void Init(CI _n) {Nt=0,n=_n;for(RI i=1;i<=n;++i) Rt[i]=0;}
I void Ins(CI id,CI v) {Ins(v,1,n,Rt[id]);}
I int Qry(CI id,CI l,CI r) {return Qry(l,r,1,n,Rt[id]);}
I void Merge(CI x,CI y) {Rt[x]=Merge(1,n,Rt[x],Rt[y]);}
};SegmentTree<N,N*LN<<1> S;
I void dfs(CI x,CI lst=0)
{
RI i;for(Sz[x]=1,S.Ins(x,x),i=lnk[x];i;i=e[i].nxt)//处理子树，合并子树线段树
e[i].to^lst&&(dfs(e[i].to,x),Sz[x]+=Sz[e[i].to],S.Merge(x,e[i].to),0);
LL res=0;RI t,t1=S.Qry(x,1,x-1),t2=Sz[x]-t1-1;
if(p[2]==1)//若y相对排名为1
{
ans+=1LL*(n-x-t2)*t2;//部分在子树外
for(RI i=lnk[x];i;i=e[i].nxt) e[i].to^lst&&//完全在子树内
(t=S.Qry(e[i].to,x+1,n),res+=1LL*(t2-t)*t);
}
else if(p[2]==2)//若y相对排名为2
{
ans+=1LL*(n-x-t2)*t1+1LL*(x-1-t1)*t2;//部分在子树外
for(RI i=lnk[x];i;i=e[i].nxt) e[i].to^lst&&//完全在子树内
(t=S.Qry(e[i].to,x+1,n),res+=1LL*(t2-t)*(Sz[e[i].to]-t));
}
else//若y相对排名为3
{
ans+=1LL*(x-1-t1)*t1;//部分在子树外
for(RI i=lnk[x];i;i=e[i].nxt) e[i].to^lst&&//完全在子树内
(t=S.Qry(e[i].to,1,x-1),res+=1LL*(t1-t)*t);
}ans+=res>>(p[2]!=2);
}
int main()
{