2019徐州网络赛 (The Preliminary Contest for ICPC Asia Xuzhou 2019)(总结+题解)

今天这场网络赛就比较舒服,(虽然一开始榜有点歪,但是基本上能做的题都做了)能A的题也不少,除了签到题,还有不少模板题,原题。最后还有一个贪心的题没有想出来,。做那么多题,也是真的有点累,(虽然套了几个板子,)

------------------------------------------(部分)题解------------------------------------------------

https://www.jisuanke.com/contest/3005?view=challenges

A. Who is better?

思路:看懂题意就很简单。怪物的数量用扩展中国剩余定理求出来,然后判输赢是斐波那契博弈。就两块的拼合。很简单。

但是一开始网上找的扩展中国剩余定理的板子,竟然WA了好多。最后发现竟然是,扩展中国剩余定理的板子问题,换个板子就A了。

代码:

#include

typedef long long ll;

#define inf 0x3f3f3f3f3f3f3f3fLL

#define maxn 20

using namespace std;

int n;

ll M[100005],A[100005];

void ex_gcd(ll a,ll b,ll &d,ll&x,ll&y)

{

if(!b)

{

d=a;

x=1;

y=0;

}else{

ex_gcd(b,a%b,d,y,x);

y-=x*(a/b);

}

}

ll gcd(ll a,ll b)

{

return b==0?a:gcd(b,a%b);

}

ll CRT()

{

ll dm,i,a,b,x,y,d;

ll c,c1,c2;

a=M[0];

c1=A[0];

for(i=1;i

{

b=M[i];

c2=A[i];

ex_gcd(a,b,d,x,y);

c=c2-c1;

if(c%d)

return -1;

dm=b/d;

x=((x*(c/d))%dm+dm)%dm;

c1=a*x+c1;

a=a*dm;

}

if(c1==0)

{

c1=1;

for(i=0;i

c1=c1*M[i]/gcd(c1,M[i]);

}

return c1;

}

ll nn,a,b,c;

int main()

{

scanf("%d",&n);

for(int i=0;i

{

scanf("%lld%lld",&M[i],&A[i]);

}

nn=CRT();

if(nn==-1) {printf("Tankernb!\n");return 0;}

a=0;b=1;

int ans=0;

for(int i=1;a+b<=1e16;i++)

{

if(a+b==nn) {ans=1;break;}

c=b;

b=a+b;

a=c;

}

if(ans==1) printf("Lbnb!\n");

else printf("Zgxnb!\n");

return 0;

}

B. so easy

思路:正解似乎是哈希+并查集思想,但是我用的map,竟然A了,然而后来发现,应该是T的..又交了几次源代码,确实卡了map的排序时间,用unordered_map就能A.这个题能A的那么快,也是人品爆棚!

代码:

#include

#define ll long long

#define inf 0x3f3f3f3f3f3f3f3fLL

#define maxn 100500

using namespace std;

int n,q,z,x;

mapma;

mapmaa;

int fin(int k)

{

if(k==-1) return -1;

if(ma[k]==0) return k;

else return ma[k]=fin(ma[k]);

}

int main()

{

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

ma[n]=-1;

while(q--)

{

scanf("%d%d",&z,&x);

if(z==1) {

ma[x]=x+1;

}

else if(z==2)

{

printf("%d\n",fin(x));

}

}

}

C. Buy Watermelon

思路:水题,判奇偶,特判2就行.

代码:

#include

#define ll long long

#define inf 0x3f3f3f3f

#define rep(i,a,b) for(register int i=(a);i<=(b);i++)

#define dep(i,a,b) for(register int i=(a);i>=(b);i--)

using namespace std;

const int maxn=2e5+5;

//const double pi=acos(-1.0);

//const double eps=1e-9;

//const ll mo=1e9+7;

int n,m,k;

int a[maxn],c[maxn];

int ans,tmp,cnt;

int flag;

char s[maxn];

bool ok[maxn];

int main()

{

int T,cas=1;

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

while(scanf("%d",&n)!=EOF)

{

if(n&1) puts("NO");

else

{

if(n>=4) puts("YES");

else puts("NO");

}

}

return 0;

}

D. Carneginon

思路:kmp找字串,模板,找找关系判判就完了.

代码:

#include

#define ll long long

#define inf 0x3f3f3f3f3f3f3f3fLL

#define maxn 100500

using namespace std;

void getnext(char *ch,int *next)

{

int x=strlen(ch);

next[0]=0;

for(int i=1,p=0;i

{

while(p>0&&ch[i]!=ch[p])

{

p=next[p-1];

}

if(ch[p]==ch[i]) p++;

next[i]=p;

}

}

int kmp(char *ch,char *chh,int *next)///查询ch内是否含有chh字串

{

int n=strlen(ch),m=strlen(chh),j=0,i=0;

while(i

{

if(ch[i]==chh[j])

{

i++;j++;

}

else

{

if(j==0) i++;

else j=next[j-1];

}

}

if(j==m) return 1;

else

return 0;

}

char t[maxn];

int q,a[maxn],b[maxn],n,m;

char s[maxn];

int main()

{

scanf("%s",t);

getnext(t,a);

n=strlen(t);

scanf("%d",&q);

while(q--)

{

scanf("%s",s);

m=strlen(s);

if(n>m)

{

getnext(s,b);

if(kmp(t,s,b)) {printf("my child!\n");}

else {printf("oh, child!\n");}

}

else if(n==m)

{

int ok=0;

for(int i=0;i

{

if(s[i]!=t[i]) {printf("friend!\n");ok=1;break;}

}

if(!ok) printf("jntm!\n");

}

else if(n

{

if(kmp(s,t,a)) {printf("my teacher!\n");}

else {printf("senior!\n");}

}

}

}

E. XKC's basketball team

思路:

先按w值排序.从大到小依次算答案,因为排序,queue也是从大到小入的队列,比当前i点的w+m大的,一定比剩下的w+m大,所以,继续往下寻找最右边的值>w+m的就可以.

代码:

#include

#define ll long long

#define inf 0x3f3f3f3f3f3f3f3fLL

#define maxn 500015

using namespace std;

ll n,m,maxr,ans[maxn];

struct AA

{

ll w,rt;

bool operator<(const AA&aa)const

{

if(w==aa.w) return rt>aa.rt;

return w>aa.w;

}

}pos[maxn];

queueq;

int main()

{

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

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

{

scanf("%lld",&pos[i].w);

pos[i].rt=i;

}

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

maxr=-1;

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

{

while(!q.empty())

{

AA x=q.front();

if(x.w>=pos[i].w+m)

{

maxr=max(maxr,x.rt);

q.pop();

}

else break;

}

ans[pos[i].rt]=(maxr>pos[i].rt)?(maxr-pos[i].rt-1):(-1);

q.push(pos[i]);

}

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

{

if(i==n) printf("%lld\n",ans[i]);

else printf("%lld ",ans[i]);

}

}

G. Colorful String

思路:马拉车,驾驾驾~

代码:

#include

#define rep(i,a,b) for(register int i=(a);i<=(b);i++)

#define dep(i,a,b) for(register int i=(a);i>=(b);i--)

using namespace std;

#define ll long long

const ll mod=1e9+7;

const int maxn=300015;

char s[maxn],t[maxn];

int a[maxn];

int Len[maxn<<1],pos,qian[maxn][27];

char tmp[maxn<<1];

int l,r,len,cnt,num;

int val[maxn];

ll ans;

int search(int la,int lb,int x)

{

int l=la,r=lb;

while(l

{

int mid=(l+r)>>1;

if(qian[mid][x]-qian[la-1][x]>0)

r=mid;

else l=mid+1;

}

return r;

}

ll query(int l,int r)

{

ll sum=0;

rep(k,0,25)

{

if(qian[r][k]-qian[l-1][k]>0)

{

int pos=search(l,r,k);

//if(cnt==3)

//cout<

sum+=(r-pos+1);

}

}

return sum;

}

int init(char *st)

{

int i,len=strlen(st);

tmp[0]='@';

for(i=1;i<=2*len;i+=2)

{

tmp[i]='#';

tmp[i+1]=st[i/2];

}

tmp[2*len+1]='#';

tmp[2*len+2]='$';

tmp[2*len+3]=0;

return 2*len+1;

}

void manacher(char *st,int len)

{

int mx=0,po=0;

for(int i=1;i<=len;i++)

{

if(mx>i)

Len[i]=min(mx-i,Len[2*po-i]);

else

Len[i]=1;

while(st[i-Len[i]]==st[i+Len[i]])

Len[i]++;

if(Len[i]+i>mx)

{

mx=Len[i]+i;

po=i;

}

l=(i-1)/2-(Len[i]-1)/2;

r=(i-1)/2+(Len[i]-1)/2;

if(Len[i]&1) r--;

//cout<

num=((r-l+2)/2);

cnt=((i-1)/2)+1;

if(cnt<=r+1) ans+=query(cnt,r+1);

//if(l<=r)

//cout<

}

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

return ;

}

int main()

{

int T,cas=1;

scanf("%s",s);

len=strlen(s);

rep(i,0,len-1)

{

a[i]=s[i]-'a';

rep(j,0,25)

qian[i+1][j]=qian[i][j];

qian[i+1][s[i]-'a']++;

}

memset(Len,0,sizeof(Len));

ans=0;

len=init(s);

manacher(tmp,len);

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

return 0;

}

/*

babab

*/

K. Center

#include

#define rep(i,a,b) for(register int i=(a);i<=(b);i++)

#define dep(i,a,b) for(register int i=(a);i>=(b);i--)

using namespace std;

#define ll long long

const ll mo=5e6+7;

const int maxn=2015;

int a[maxn],n;

ll x[maxn],y[maxn];

ll ans;

mapmp,mmp;

map::iterator it,itt;

ll mid(ll a,ll b)

{

return (a+b)/2;

}

int main()

{

int T,cas=1;

scanf("%d",&n);

rep(i,1,n)

{

scanf("%lld%lld",&x[i],&y[i]);

x[i]*=2;y[i]*=2;

mmp[x[i]*mo+y[i]]++;

rep(j,1,i-1)

mp[mid(x[i],x[j])*mo+mid(y[i],y[j])]++;

}

int ans=0;

ll ansx=0,ansy=0;

for(it=mp.begin();it!=mp.end();it++)

{

int num=(*it).second;

if(num>ans)

{

ans=num;

ansx=(*it).first/mo;

ansy=(*it).first%mo;

}

}

ans=n*2+5;

x[++n]=ansx;

y[n]=ansy;

rep(j,1,n)

{

mmp.clear();

rep(i,1,n-1)

mmp[x[i]*mo+y[i]]++;

int as=0;

rep(i,1,n-1)

{

ll xx=2*x[j]-x[i];

ll yy=2*y[j]-y[i];

if(mmp[xx*mo+yy]==0)

{

mmp[xx*mo+yy]++;

as++;

}

}

if(as

}

if(n==1) ans=0;

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

return 0;

}

Top