这套题真的有点传奇了,考了两次。虽然银川赛区名声不行,但这套题质量还是过硬的,所以来补一下,还是收获颇丰。

A. Maximum Element In A Stack

题意

实现一个支持查询当前栈中元素的最大值的栈。

题解

最大栈的模板题,相当于在原始栈的基础上再开一个栈存前缀最大值,pop操作与原栈同步就好。

代码

#include

#include

#include

#include

#include

using namespace std;

typedef long long LL;

int n,p,q,m;

unsigned int SA,SB,SC;

unsigned int rng61(){

SA^=SA<<16;

SA^=SA>>5;

SA^=SA<<1;

unsigned int t=SA;SA=SB;

SB=SC;

SC^=t^SA;

return SC;

}

stack sta,ms;

void push(int x){

if(!ms.empty()) ms.push(max(x,ms.top()));

else ms.push(x);

sta.push(x);

}

void pop(){

if(!ms.empty()) ms.pop(),sta.pop();

}

void solve(int Case){

while(!ms.empty()) sta.pop(),ms.pop();

scanf("%d%d%d%d%u%u%u",&n,&p,&q,&m,&SA,&SB,&SC);

LL ans=0;

for(int i=1;i<=n;i++){

if(rng61()%(p+q)

else pop();

if(!ms.empty()) ans^=1ll*ms.top()*i;

}

printf("Case #%d: %lld\n",Case,ans);

}

int main(){

int T;scanf("%d",&T);

for(int i=1;i<=T;i++) solve(i);

return 0;

}

B. Rolling The Polygon

题意

给你一个多边形,沿逆时针滚一圈,要求多边形中某一点的运动路程。

题解

其实可以发现多边形沿一个角滚一下,这个点的轨迹是一个以该点到滚动角的距离为半径,滚动角的补角为角度的扇形,可以直接把这个距离算出来。

代码

#include

#include

#include

#include

#include

using namespace std;

int n;

double x[55],y[55],ag[55],dis[55];

double calc(int i,int j){

double res=(x[i]-x[j])*(x[i]-x[j]);

res+=(y[i]-y[j])*(y[i]-y[j]);

return sqrt(res);

}

double calcangle(int i,int j,int k){

double res=x[i]*y[j]+x[j]*y[k]+x[k]*y[i]-y[j]*x[k]-y[i]*x[j]-y[k]*x[i];

double a=calc(i,j),b=calc(k,j),c=calc(i,k);

res/=a*b;

res=asin(res);

if(c*c>b*b+a*a) return res;

else return 3.1415926525-res;

}

void solve(int Case){

scanf("%d",&n);

for(int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]);

scanf("%lf%lf",&x[0],&y[0]);

double ans=0;

for(int i=1,a=i-1,b=i,c=i+1;i<=n;i++,a--,b--,c--){

if(a<1) a+=n;if(b<1) b+=n;if(c<1) c+=n;

ag[i]=calcangle(a,b,c);

dis[i]=calc(0,b);

//printf("(%.0lf,%.0lf),(%.0lf,%.0lf),(%.0lf,%.0lf) angle=%lf dis=%lf\n",x[a],y[a],x[b],y[b],x[c],y[c],ag[i],dis[i]);

ans+=ag[i]*dis[i];

}

printf("Case #%d: %.3lf\n",Case,ans);

}

int main(){

int T;scanf("%d",&T);

for(int i=1;i<=T;i++) solve(i);

return 0;

}

C. Caesar Cipher

本场白给题

#include

#include

#include

#include

using namespace std;

int n,m;

char s1[55],s2[55],t[55];

void solve(int Case){

scanf("%d%d",&n,&m);

scanf("%s%s%s",s1+1,s2+1,t+1);

int sub=s1[1]-s2[1];

for(int i=1;i<=m;i++) t[i]=(t[i]-'A'+sub+26)%26+'A';

printf("Case #%d: %s\n",Case,t+1);

}

int main(){

int T;scanf("%d",&T);

for(int i=1;i<=T;i++) solve(i);

return 0;

}

D. Take Your Seat

题意

杜华是个疯子,有一天他去坐飞机,轮到他上机时,他会从没有人的位置中随机选择一个位置坐下。如果其他乘客发现自己位置被人占之后,他也会疯掉,从没有人的位置中随机选择一个坐下。那么问题来了:

1.共有 \(n\) 个乘客,编号 \(1,2,...,n\),对应座位号 \(1,2,...,n\),依次登机,杜华是 \(1\) 号乘客,问第 \(n\) 位乘客能做 \(n\) 号位置的概率。

2.共有 \(m\) 个乘客,编号 \(1,2,...,m\),对应座位号 \(1,2,...,m\),随机顺序登机,问最后一个登机的乘客能坐到自己对应位置上的概率。

题解

概率杀我。

先看第一个问题:

如果杜华坐了 \(1\) 号,那么此时概率 \(=1\) 。

如果杜华坐了 \(i(1

如果杜华坐了 \(n\) 号,当然概率直接为 \(0\)。

那么如果设该问题的概率为 \(f[n]\),可知 \(f[n]=\frac{1+f[n-1]+f[n-2]+...+f[2]}{n}\) ,那这时就可以计算了,其实手算一下,可以发现 \(f[n]=\frac{1}{2}\)。

再来看第二个问题,可以发现:

如果杜华是第 \(i\) 个登机的人,那么这个问题就相当于规模为 \(m-i+1\) 的一问题。

那么设二问题概率为 \(g[m]\),可得 \(g[m]=\frac{f[m]+f[m-1]+...+f[1]}{m}\)。

代码

#include

#include

#include

#include

using namespace std;

double f[55],g[55];

void solve(int Case){

int n,m;

scanf("%d%d",&n,&m);

printf("Case #%d: %.6lf %.6lf\n",Case,f[n],g[m]);

}

int main(){

f[1]=g[1]=1;

double sum=0;

for(int i=2;i<=50;i++){

sum+=f[i-1];

f[i]=sum/i;

g[i]=(sum+f[i])/i;

}

int T;scanf("%d",&T);

for(int i=1;i<=T;i++) solve(i);

return 0;

}

E. 2-3-4 Tree

题意

给出234树的形态和插入方法,然后依次插入一个 \(n\) 的全排列,要求输出最后234树的前序遍历。

如果总共加入234树的值不超过 \(3\) 个,那么这棵树显然只有根节点一个点。否则从根节点开始按一下规律插入值:

1.如果当前节点是一个 '4节点':

将这个节点中间的值拿出来,左右两边的值和四个儿子构成两个 '2节点'。

如果原 '4节点' 是根节点,那么把中间值重新构成一个根节点,让新生成的两个 '2节点' 成为它的儿子。

否则把中间值插入原 '4节点' 的父节点,新生成的两个 '2节点' 成为原 '4节点' 父节点的儿子。

2.如果当前节点是叶节点了,那么直接将值加入当前节点中,插入完成。

3.否则:

寻找值属于当前节点的哪个子节点。

进入子节点继续从第 \(1\) 步开始判断。

题解

有点变态的数据结构模拟题啊……读懂题都要下一番功夫。

其实构造这个234树的难点就在于对 '4节点' 的调整。我们来考虑一下:

1.如果当前节点为 '4节点' 并且当前节点是根节点:

新建一个节点,将右值存入,它的1儿子为原4节点的3儿子,2儿子为原4节点的4儿子。

再新建一个节点,将中值存入,它的1儿子为原4节点,2儿子为刚刚新建的节点。指定它为新的根节点。

设定这 \(3\) 个点的大小信息,分配儿子时也不要忘记重新定向儿子的父亲。

2.如果当前节点为 '4节点' 并且当前节点不是根节点:

新建一个节点,将右值存入,它的1儿子为原4节点的3儿子,2儿子为原4节点的4儿子。

将中值加入原4节点的父节点。让新建的节点成为原4节点的父节点的又一个儿子。

调整节点信息,并对父节点中的值排序,对父节点的所有儿子进行排序。

3.经过调整之后,从父节点开始,寻找应该插入哪颗子树。注意这时如果父节点是 '4节点',也不调整了。

如果是不需要调整的节点,那就很好找了。

要注意的点:往一个节点中插入值之后,一定要排序。向一个节点加入了儿子,也要对它所有儿子排序;加入儿子同时也要将儿子的父亲指针指向父节点。

代码

#include

#include

#include

#include

#include

using namespace std;

const int N=5010;

int n;

bool cmp(int x,int y);

struct _234Tree{

int data[N][3],siz[N],tr[N][4],fa[N],rt,tot;

void init(){

memset(data,0,sizeof(data));

memset(tr,0,sizeof(tr));

memset(fa,0,sizeof(fa));

memset(siz,0,sizeof(siz));

rt=tot=0;

}

void insert(int id,int val){

if(siz[id]==3){

if(id==rt){

rt=++tot;int rs=++tot;

data[rt][0]=data[id][1],siz[rt]=1,tr[rt][0]=id,tr[rt][1]=rs;

data[rs][0]=data[id][2],siz[rs]=1,tr[rs][0]=tr[id][2],tr[rs][1]=tr[id][3];fa[rs]=rt;

fa[tr[id][2]]=rs;fa[tr[id][3]]=rs;

siz[id]=1;fa[id]=rt;

}

else{

int par=fa[id],rs=++tot;

data[par][siz[par]++]=data[id][1],tr[par][siz[par]]=rs;

data[rs][0]=data[id][2],siz[rs]=1,tr[rs][0]=tr[id][2],tr[rs][1]=tr[id][3];fa[rs]=par;

fa[tr[id][2]]=rs;fa[tr[id][3]]=rs;

siz[id]=1;

sort(data[par],data[par]+siz[par]);

sort(tr[par],tr[par]+siz[par]+1,cmp);

}

int par=fa[id];

if(val

else if(siz[par]==1||val

else if(siz[par]==2||val

else insert(tr[par][3],val);

return;

}

if(!tr[id][0]){

data[id][siz[id]++]=val;

sort(data[id],data[id]+siz[id]);

return;

}

if(val

else if(siz[id]==1||val

else if(siz[id]==2||val

}

void dfs(int id){

if(!id) return;

for(int i=0;i

for(int i=0;i<=siz[id];i++) dfs(tr[id][i]);

}

}_234;

bool cmp(int x,int y){

return _234.data[x][0]<_234.data[y][0];

}

void solve(int Case){

printf("Case #%d:\n",Case);

_234.init();

scanf("%d",&n);

int x;

scanf("%d",&x);

_234.rt=_234.tot=1;

_234.data[1][0]=x;

_234.siz[1]=1;

for(int i=2;i<=n;i++){

scanf("%d",&x);

_234.insert(_234.rt,x);

}

_234.dfs(_234.rt);

}

int main(){

int T;scanf("%d",&T);

for(int i=1;i<=T;i++) solve(i);

return 0;

}

F. Moving On

题意

有一个点权边权图,多组询问,问从 \(u\) 到 \(v\) 经过的点点权不超过 \(w\) 的路径的最小值。

题解

如果熟悉floyd最短路的话,这道题还是很简单的。

首先从 \(n\) 的范来说,可以肯定用floyd。

然后可以将询问离线,按 \(w\) 排序,把所有点也按点权排序。

双指针,如果当前询问的 \(w\) 大于已经处理的点的点权,尝试继续处理之后的点。

代码

#include

#include

#include

#include

#include

#define ff first

#define ss second

using namespace std;

typedef long long LL;

typedef pair PII;

const int N=2e5+10;

int n,m,ans[N];

int g[210][210];

PII p[210];

struct Qure{

int u,v,w,id;

}q[N];

bool cmp(Qure a,Qure b){return a.w

void solve(int Case){

scanf("%d%d",&n,&m);

for(int i=1;i<=n;i++) scanf("%d",&p[i].ff),p[i].ss=i;

for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&g[i][j]);

for(int i=1;i<=m;i++) scanf("%d%d%d",&q[i].u,&q[i].v,&q[i].w),q[i].id=i;

sort(p+1,p+n+1);

sort(q+1,q+m+1,cmp);

for(int i=1,j=0;i<=m;i++){

while(j

int k=p[++j].ss;

for(int u=1;u<=n;u++)

for(int v=1;v<=n;v++)

g[u][v]=min(g[u][v],g[u][k]+g[k][v]);

}

ans[q[i].id]=g[q[i].u][q[i].v];

}

printf("Case #%d:\n",Case);

for(int i=1;i<=m;i++) printf("%d\n",ans[i]);

}

int main(){

int T;scanf("%d",&T);

for(int i=1;i<=T;i++) solve(i);

return 0;

}

G. Factories

题意

给一颗树,要求你从选 \(k\) 个叶节点,使得这 \(k\) 个叶节点各自之间的距离之和最短。

题解

这是个树形背包的板子题。

如果从以 \(v\) 为根节点的子树中选定了 \(i\) 个节点,那么在所有 \(\frac{k\times(k-1)}{2}\) 条路径中,边 \(v-fa_v\) 被经过了 \(i\times (k-i)\) 次,所以可以推出方程:

\[f[u][i]=min\big(f[u][i],f[u][i-j]+f[v][j]+w_{uv}\times j\times (k-j)\big)

\]

当然要注意,要用额外的数组来存 \(f[u][i]\),统计玩一颗子树之后再付给 \(f[u][i]\),这不是为了加快速度,而是为了避免重复统计同一颗子树中的信息。

这里我想起了 CCF 某次的第 5 题,我好像就是没用开另外的数组,导致只有 70 分。

代码

#include

#include

#include

#include

#include

#define ff first

#define ss second

using namespace std;

typedef long long LL;

typedef pair PII;

const int N=1e5+10;

const int inf=0x3f3f3f3f;

const LL INF=0x3f3f3f3f3f3f3f3f;

int n,k,cnt[N],d[N];

LL f[N][110],tmp[110];

int head[N],to[N*2],val[N*2],nxt[N*2],tot;

int read(){

int x=0,f=1;char c=getchar();

while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}

while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}

return x*f;

}

void add(int u,int v,int w){

to[++tot]=v;val[tot]=w;nxt[tot]=head[u];head[u]=tot;

}

void dfs(int u,int fa){

cnt[u]=0;f[u][0]=0;

if(d[u]==1) f[u][1]=0,cnt[u]=1;

if(d[u]==1) return;

for(int i=1;i<=k;i++) f[u][i]=INF;

for(int i=head[u];i;i=nxt[i]){

if(to[i]==fa) continue;

dfs(to[i],u);

cnt[u]+=cnt[to[i]];

if(cnt[u]>k) cnt[u]=k;

int v=to[i];LL w=val[i];

for(int j=0;j<=cnt[u];j++) tmp[j]=INF;

for(int j=0;j<=cnt[u];j++)

for(int p=0;p<=cnt[v]&&p<=j;p++)

tmp[j]=min(tmp[j],f[u][j-p]+f[v][p]+w*p*(k-p));

for(int j=0;j<=cnt[u];j++) f[u][j]=tmp[j];

}

}

void solve(int Case){

printf("Case #%d: ",Case);

n=read(),k=read();

for(int i=1;i<=n;i++) head[i]=0,d[i]=0;

tot=0;

int u,v,w;

for(int i=1;i

u=read(),v=read(),w=read();

add(u,v,w);add(v,u,w);

d[u]++;d[v]++;

}

if(n==2){

if(k==2) printf("%d\n",w);

else printf("0\n");

return;

}

int root=1;

while(d[root]<2) root++;

dfs(root,0);

printf("%lld\n",f[root][k]);

}

int main(){

int T;scanf("%d",&T);

for(int i=1;i<=T;i++) solve(i);

return 0;

}

H. Fight Against Monsters

题意

有 \(n\) 个怪兽,每个怪兽有血量和攻击力,你每回合会收到所有没有死掉的怪兽的依次攻击,问你杀死所有怪兽最少损失多少血量。

题解

微扰法贪心。

首先可以算出每只怪兽的血量可以顶我几回合的攻击,记为 \(k_i\),每只怪兽的攻击力记为 \(a_i\),那么假如我按顺序杀怪兽损失血量最少,那么我损失血量为:

\[a_1\times k_1+a_2\times (k_1+k_2)+...+a_n\times \sum_{i=1}^{n}k_i

\]

假如我先杀第 \(2\) 只,再杀第 \(1\) 只怪兽,损失血量为:

\[a_2\times k_2+a_1\times (k_1+k_2)+...+a_n\times \sum_{i=1}^{n}k_i

\]

此时我受到的伤害肯定不会减少,那么:

\[\begin{aligned}a_1\times k_1+a_2\times (k_1+k_2)+...+a_n\times \sum_{i=1}^{n}k_i&\le a_2\times k_2+a_1\times (k_1+k_2)+...+a_n\times \sum_{i=1}^{n}k_i\\a_1\times k_1+a_2\times k_1+a_2\times k2&\le a_2\times k_2+a_1\times k_1+a_1\times k_2\\a_2\times k_1&\le a_1\times k_2\end{aligned}

\]

那么只需要按 \(a_2\times k_1\le a_1\times k_2\) 这个顺序对怪兽排序,依次杀掉就可以了。

代码

#include

#include

#include

#include

#include

#include

#define ff first

#define ss second

using namespace std;

typedef long long LL;

typedef pair PII;

const int N=1e5+10;

int n;

PII p[N];

bool cmp(PII a,PII b){return a.ss*b.ff

void solve(int Case){

printf("Case #%d: ",Case);

scanf("%d",&n);

for(int i=1;i<=n;i++) {

scanf("%d%d",&p[i].ss,&p[i].ff);

LL num=0,sum=0;

while(sum

p[i].ss=num;

}

sort(p+1,p+n+1,cmp);

LL ans=0,sum=0;

for(int i=1;i<=n;i++){

sum+=p[i].ss;

ans+=sum*p[i].ff;

}

printf("%lld\n",ans);

}

int main(){

int T;scanf("%d",&T);

for(int i=1;i<=T;i++) solve(i);

return 0;

}

K. Vertex Covers

题意

定义完全覆盖点集 \(S\):\(G\) 中任意一条边总有至少 \(1\) 个顶点在 \(S\) 中。

\(S\) 的积:\(S\) 中所有点的点权之积;空集的积为 \(1\)。

求 \(G\) 的所有 \(S\) 的积之和。

题解

从 \(n\) 的范围来说,肯定是双向搜索。可以将前 \(\frac{n}{2}\) 个点和其余 \(n-\frac{n}{2}\) 个点分为两堆,分别枚举每堆的状态,算出每种状态的积。

这两堆种,如果有边在一堆之内,那么这个边的两端至少有一个点要被选。如果是有边在两堆之间,如果一堆的状态确定,可以发现另一堆最差的状态也确定了,然后另一堆中没被选的点其实是可选可不选,这就是这个集合的超集,这个超集之和就是这一堆所有方案之和。

计算超集之和就是高维前缀和:

for(int u=0;u

for(int sta=0;sta<1<

if(!(sta&1<

当然高维前缀和也可以计算子集之和:

for(int u=0;u

for(int sta=0;sta<1<

if(sta&1<

代码

#include

#include

#include

#include

#include

using namespace std;

typedef long long LL;

typedef pair PII;

const int M=1e6+10;

LL a[40],ans,fl[M],fr[M];

int n,m,mod;

vector g[40];

void solve(int Case){

ans=0;

scanf("%d%d%d",&n,&m,&mod);

for(int i=0;i

for(int i=0;i

for(int i=0,u,v;i

scanf("%d%d",&u,&v);

u--;v--;

g[u].push_back(v);

g[v].push_back(u);

}

int nl=n/2,nr=n-nl;

for(int sta=0;sta<(1<

bool flag=true;fl[sta]=1;

for(int u=0;u

for(int v:g[u]){

if(v>=nl) continue;

if(!(sta&1ll<

}

if(!flag) {fl[sta]=0;break;}

if(sta&1ll<

}

}

//高维前缀和

for(int u=0;u

for(int sta=0;sta<1<

if(!(sta&1<

for(int sta=0;sta<(1<

bool flag=true;fr[sta]=1;

int link=0;

for(int i=0;i

int u=nl+i;

for(int v:g[u])

if(v

if(!(sta&1<

}

else{

int j=v-nl;

if(!(sta&1<

}

if(!flag) {fr[sta]=0;break;}

if(sta&1<

}

ans=(ans+fr[sta]*fl[link])%mod;

}

printf("Case #%d: %lld\n",Case,ans);

}

int main(){

int T;scanf("%d",&T);

for(int i=1;i<=T;i++) solve(i);

return 0;

}

L. Continuous Intervals

题意

给数列 \(a_1,a_2,...,a_n\),问有多少个连续子序列 \(a_1,a_2,...,a_m\) 满足排序后 \(a_i-a_{i-1}\le 1\)。

题解

其实这个题和蓝桥杯2013的最后一题基本一致,只是蓝桥杯是全排列,而这个是任意数。相似问题:

蓝桥杯2013省赛10题

CodeForces 193D

这类问题当然是用线段树解决的,但是用法有两种,我这里选择在原数列上来,这样形象一点,还有一种是在自然数列上进行,在这道题上就没那么好想、好写了。

设 f[i,r] 为 \(a_i,a_{i+1},...,a_r\) 排序后是几段,那么线段树可以维护 \(f[1,r],f[2,r],...,f[r,r]\)。

此时我加入 \(a_{r+1}\),观察 \(f[1,r+1],f[2,r+1],...,f[r+1,r+1]\) 相对 \(f[1,r],f[2,r],...,f[r,r]\) 会发生什么变化。

可以发现,如果数 \(a_{r+1}\) 上一次出现的位置在 \(pos\) 的话,\(f[1,r+1],f[2,r+1],...,f[pos,r+1]\) 相对之前是不会有变化的,因为本来这些区间里就有 \(a_{r+1}\),你再加一个 \(a_{r+1}\) 当然不会有任何影响。

如果 \(a_{r+1}-1\) 和 \(a_{r+1}+1\) 中有一个数出现在 \(pos1(pos1>l)\) 位置,那么 \(f[i,r+1]=f[i,r](l

如果 \(a_{r+1}-1\) 和 \(a_{r+1}+1\) 这两个数分别出现在 \(pos1,pos2(l

当然还有这两个数都没有出现的情况,直接所有区间都+1就行了,因为 \(a_{r+1}\) 在这些区间里很孤单。

代码

#include

#include

#include

#include

#include

using namespace std;

typedef long long LL;

const int N=1e5+10;

int n,a[N];

map lastpos;

struct SegTree{

#define mid (l+r>>1)

int minv[N*4],tag[N*4],num[N*4];

void build(int id,int l,int r){

minv[id]=tag[id]=0,num[id]=r-l+1;

if(l==r) return;

build(id<<1,l,mid);

build(id<<1|1,mid+1,r);

}

void pushdown(int id){

minv[id<<1]+=tag[id];tag[id<<1]+=tag[id];

minv[id<<1|1]+=tag[id];tag[id<<1|1]+=tag[id];

tag[id]=0;

}

void pushup(int id){

minv[id]=min(minv[id<<1],minv[id<<1|1]);

num[id]=0;

if(minv[id]==minv[id<<1]) num[id]+=num[id<<1];

if(minv[id]==minv[id<<1|1]) num[id]+=num[id<<1|1];

}

void upd(int id,int l,int r,int L,int R,int x){

if(L<=l&&r<=R) {minv[id]+=x;tag[id]+=x;return;}

if(tag[id]) pushdown(id);

if(L<=mid) upd(id<<1,l,mid,L,R,x);

if(R>mid) upd(id<<1|1,mid+1,r,L,R,x);

pushup(id);

}

int ask(int id,int l,int r,int L,int R){

if(L<=l&&r<=R) return minv[id]==1?num[id]:0;

if(tag[id]) pushdown(id);

int res=0;

if(L<=mid) res+=ask(id<<1,l,mid,L,R);

if(R>mid) res+=ask(id<<1|1,mid+1,r,L,R);

return res;

}

#undef mid

}tr;

void solve(int Case){

lastpos.clear();

scanf("%d",&n);

for(int i=1;i<=n;i++) scanf("%d",&a[i]);

tr.build(1,1,n);

LL ans=0;

for(int i=1;i<=n;i++){

int l=lastpos[a[i]]+1,pos1=lastpos[a[i]-1],pos2=lastpos[a[i]+1];

if(pos1>pos2) swap(pos1,pos2);

if(pos1>=l) tr.upd(1,1,n,l,pos1,-1),tr.upd(1,1,n,pos2+1,i,1);

else if(pos2>=l) tr.upd(1,1,n,pos2+1,i,1);

else tr.upd(1,1,n,l,i,1);

ans+=tr.ask(1,1,n,1,i);

lastpos[a[i]]=i;

}

printf("Case #%d: %lld\n",Case,ans);

}

int main(){

int T;scanf("%d",&T);

for(int i=1;i<=T;i++) solve(i);

return 0;

}

Copyright © 2088 1978年阿根廷世界杯|世界杯克罗地亚|建校世界杯体育教育站|pendiriankampus.com All Rights Reserved.
友情链接