1. 程式人生 > 其它 >The 18th Zhejiang Provincial Collegiate Programming Contest

The 18th Zhejiang Provincial Collegiate Programming Contest

題解:

https://files.cnblogs.com/files/clrs97/ZJCPC2021analyze.zip

Code:

A. League of Legends

#include<cstdio>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
typedef long long LL;
int main()
{
    int x=0,y=0;
    rep(i,5){int z;scanf("%d",&z);x+=z;}
    rep(i,5){int z;scanf("%d",&z);y+=z;}
    puts(x>=y?"Blue":"Red");
    return 0;
} 

  

B. Restore Atlantis

//n log^2 m + q sqrt(n) + m^2
#include<cstdio>
#include<queue>
using namespace std;
const int N=100005,M=2000,K=(N>>8)+5;
int n,m,i,j,ga[M+5],gd[M+5],v[N<<1],nxt[N<<1],ed,st[M+5][M+5],en[M+5][M+5];
bool del[N];
struct Rect{int l,r,v;}rect[N];
priority_queue<int>val[4111];
int g[N],nxtq[N],w[N],ans[N],G[N],V[M*M+5],NXT[M*M+5],ED;
int be[K],sum[K],f[N];
inline void add(int&x,int y){v[++ed]=y;nxt[ed]=x;x=ed;}
void clr(int x,int a,int b){
  while(!val[x].empty())val[x].pop();
  if(a==b)return;
  int mid=(a+b)>>1;
  clr(x<<1,a,mid);
  clr(x<<1|1,mid+1,b);
}
void ins(int x,int a,int b,int c,int d,int p){
  if(c<=a&&b<=d){
    val[x].push(p);
    return;
  }
  int mid=(a+b)>>1;
  if(c<=mid)ins(x<<1,a,mid,c,d,p);
  if(d>mid)ins(x<<1|1,mid+1,b,c,d,p);
}
void dfs(int x,int a,int b,int c){
  while(!val[x].empty()){
    int t=val[x].top();
    if(del[t]){
      val[x].pop();
      continue;
    }
    if(c<t)c=t;
    break;
  }
  if(a==b){
    st[i][a]=c;
    return;
  }
  int mid=(a+b)>>1;
  dfs(x<<1,a,mid,c);
  dfs(x<<1|1,mid+1,b,c);
}
void init(){
  for(i=1;i<=M;i++){
    for(j=ga[i];j;j=nxt[j])ins(1,1,M,rect[v[j]].l,rect[v[j]].r,rect[v[j]].v);
    dfs(1,1,M,0);
    for(j=gd[i];j;j=nxt[j])del[rect[v[j]].v]=1;
  }
}
inline void modify(int x){
  sum[x>>8]++;
  f[x]++;
}
inline int ask(int x){
  int ret=0,X=x>>8,i;
  for(i=0;i<X;i++)ret+=sum[i];
  for(i=be[X];i<=x;i++)ret+=f[i];
  return ret;
}
int main(){
  scanf("%d%d",&n,&m);
  for(i=1;i<=n;i++){
    int xl,xr,yl,yr;
    scanf("%d%d%d%d",&xl,&yl,&xr,&yr);
    xl++,yl++;
    rect[i].l=yl;
    rect[i].r=yr;
    rect[i].v=i;
    add(ga[xl],i);
    add(gd[xr],i);
  }
  for(i=1;i<=m;i++){
    int l,r;
    scanf("%d%d",&l,&r);//l<=st&&en<=r
    w[i]=r;
    nxtq[i]=g[l];
    g[l]=i;
  }
  init();
  for(i=1;i<=M;i++)for(j=1;j<=M;j++)en[i][j]=st[i][j];
  for(i=1;i<=n;i++)rect[i].v=n-i+1,del[i]=0;
  clr(1,1,M);
  init();
  for(i=1;i<=M;i++)for(j=1;j<=M;j++)if(en[i][j]){
    int x=n-st[i][j]+1;
    V[++ED]=en[i][j];
    NXT[ED]=G[x];
    G[x]=ED;
    //if(x>en[i][j])printf("! (%d,%d) st=%d en=%d %d\n",i,j,x,en[i][j],st[i][j]);
  }
  for(i=n;i;i--)be[i>>8]=i;
  for(i=n;i;i--){
    for(j=G[i];j;j=NXT[j])modify(V[j]);
    for(j=g[i];j;j=nxtq[j])ans[j]=ask(w[j]);
  }
  for(i=1;i<=m;i++)printf("%d\n",ED-ans[i]);
}

  

C. Cube

#include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;++i)
using namespace std;
struct poi{
    int x,y,z;
    poi operator+(poi p){return (poi){x+p.x,y+p.y,z+p.z};}
    poi operator-(poi p){return (poi){x-p.x,y-p.y,z-p.z};}
    int operator%(poi p){return x*p.x+y*p.y+z*p.z;}
    int dis2(){return *this%*this;}
    void scan(){scanf("%d%d%d",&x,&y,&z);}
    bool operator==(poi p){return x==p.x&&y==p.y&&z==p.z;}
}a[8],b[8];
bool cmp_dis2(poi a,poi b){
    return a.dis2()<b.dis2();
}
bool cmp_xyz(poi a,poi b){
    if(a.x!=b.x)return a.x<b.x;
    if(a.y!=b.y)return a.y<b.y;
    return a.z<b.z;
}
bool check(){
    if(a[1].dis2()==0)return 0;
    if(a[1].dis2()!=a[2].dis2())return 0;
    if(a[2].dis2()!=a[3].dis2())return 0;
    if(a[1]%a[2]!=0)return 0;
    if(a[2]%a[3]!=0)return 0;
    if(a[1]%a[3]!=0)return 0;
    rep(i,8){
        poi t=(poi){0,0,0};
        if(i&1)t=t+a[1];
        if(i&2)t=t+a[2];
        if(i&4)t=t+a[3];
        b[i]=t;
    }
    sort(a,a+8,cmp_xyz);
    sort(b,b+8,cmp_xyz);
    rep(i,8)if(!(a[i]==b[i]))return 0;
    return 1;
}
int T;
int main(){
    for(scanf("%d",&T);T--;){
        rep(i,8)a[i].scan();
        rep(i,8)a[i]=a[i]-a[7];
        sort(a,a+8,cmp_dis2);
        puts(check()?"YES":"NO");
    }
    return 0;
}

  

D. Shortest Path Query

#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,int>P;
const int N=100005,K=17,M=200005;
const ll inf=1LL<<60;
int n,m,i,S,x,y,z,g[N],v[M<<1],w[M<<1],nxt[M<<1],ed,dep[N];
ll d[N],f[N][K];//f[i][j]=dis(i,i>>j)
priority_queue<P,vector<P>,greater<P> >q;
inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
void dfs1(int x){
  if(x>n)return;
  d[x]=inf;
  dfs1(x<<1);
  dfs1(x<<1|1);
}
void dfs2(int x,int y){
  if(x>n)return;
  f[x][y]=d[x];
  dfs2(x<<1,y+1);
  dfs2(x<<1|1,y+1);
}
inline void ext(int x,ll y){
  if(x<S)return;
  if(d[x]<=y)return;
  q.push(P(d[x]=y,x));
}
inline int lca(int x,int y){
  for(;x!=y;x>>=1)if(dep[x]<dep[y])swap(x,y);
  return x;
}
int main(){
  scanf("%d%d",&n,&m);
  while(m--){
    scanf("%d%d%d",&x,&y,&z);
    add(x,y,z);
    add(y,x,z);
  }
  for(i=1;i<=n;i++)dep[i]=dep[i>>1]+1;
  for(S=1;S<=n;S++){
    dfs1(S);
    ext(S,0);
    while(!q.empty()){
      P t=q.top();q.pop();
      if(d[t.second]<t.first)continue;
      for(i=g[t.second];i;i=nxt[i])ext(v[i],t.first+w[i]);
    }
    dfs2(S,0);
  }
  scanf("%d",&m);
  while(m--){
    scanf("%d%d",&x,&y);
    z=lca(x,y);
    ll ans=inf;
    int A=dep[x]-dep[z],B=dep[y]-dep[z];
    while(z){
      ans=min(ans,f[x][A]+f[y][B]);
      z>>=1,A++,B++;
    }
    if(ans==inf)ans=-1;
    printf("%lld\n",ans);
  }
}

  

E. Specially Super Rare

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
const int N=10000005,S=13331,K=1000;
int n,m,i,val,ans,pre[K<<1],nxt[K<<1];
char a[N],b[N];
ull p[N],f[N],g[N];
inline void up(int&a,int b){a<b?(a=b):0;}
inline ull ask(int l,int r,ull*f){return f[r]-f[l-1]*p[r-l+1];}
inline int lcp(int A,int B){
  if(A>n||B>n)return 0;
  if(a[A]!=b[B])return 0;
  int l=1,r=min(n-A+1,n-B+1),mid,t=0;
  while(l<=r){
    mid=(l+r)>>1;
    if(ask(A,A+mid-1,f)==ask(B,B+mid-1,g))l=(t=mid)+1;else r=mid-1;
  }
  return t;
}
int main(){
  scanf("%s%d",a+1,&m);
  n=strlen(a+1);
  for(i=1;i<=n;i++)b[i]=a[n-i+1];
  for(p[0]=i=1;i<=n;i++){
    p[i]=p[i-1]*S;
    f[i]=f[i-1]*S+a[i];
    g[i]=g[i-1]*S+b[i];
  }
  while(1){
    for(i=-ans-1;i<=ans+1;i++)nxt[i+K]=-1;
    for(i=-ans;i<=ans;i++)if(~pre[i+K]){
      //dp[ans][i]=pre[i+M]
      val=pre[i+K];//[1..val] [1..val+i]
      val+=lcp(val+1,val+i+1);
      //printf("dp[%d][%d]=%d\n",ans,i,val);
      if(val==n&&!i)return printf("%d",n-ans/2),0;
      if(val<n)up(nxt[i-1+K],val+1);
      if(val+i<n)up(nxt[i+1+K],val);
    }
    ans++;
    for(i=-ans;i<=ans;i++)pre[i+K]=nxt[i+K];
  }
}

  

F. Fair Distribution

#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long LL;
 
int a, b;
// a - 
// b +
int gao(int bb, int dd) {
    return (bb + dd - 1) / dd * dd;
}
 
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d",&a,&b);
        int ans = 1e9;
        for (int i=1;i<=20000;i++) {
            // sub a to i
            if (i <= a) {
                int tmp = a - i + gao(b, i) - b;
                ans = min(ans, tmp);
            }
            // give each one i
            int newb = gao(b, i);
            int newa = newb / i;
            if (newa <= a) {
                ans = min(ans, a - newa + newb - b);
            }
        }
        printf("%d\n",ans);
    }
}

  

G. Wall Game

#include<bits/stdc++.h>
#define ll long long
#define db long double
using namespace std;
 
const int dx[]={0,1,-1,1,-1,0};
const int dy[]={-1,-1,0,0,1,1};
const int maxn = 510000;
 
map< pair<int,int> ,int >mp; int cnt;
 
int n;
int fa[maxn],s[maxn];
int findfa(const int x){ return fa[x]==x?x:fa[x]=findfa(fa[x]); }
 
void merge(int x,int y,int i)
{
	for(int k=0;k<6;k++) 
	{
		if(mp.count(make_pair(x+dx[k],y+dy[k]))!=0)
		{
			int j=mp[make_pair(x+dx[k],y+dy[k])];
			int f1=findfa(i),f2=findfa(j);
			s[f1]--; s[f2]--;
			if(f1!=f2)
			{
				fa[f2]=f1;
				s[f1]+=s[f2];
			}
		}
	}
}
 
int main()
{
	ios_base::sync_with_stdio(false);
	
	//freopen("tmp.in","r",stdin);
	
	cin>>n;
	while(n--)
	{
		int op,x,y; cin>>op>>x>>y;
		pair<int,int>temp=make_pair(x,y);
		if(op==1)
		{
			if(mp.count(temp)==0)
			{
				mp[temp]=++cnt;
				fa[cnt]=cnt;
				s[cnt]=6;
				merge(x,y,cnt);
			}
		}
		else cout<<s[findfa(mp[temp])]<<endl;
	}
	
	
	return 0;
}

  

H. Grammy and HearthStone

#include<bits/stdc++.h>
using namespace std;
int a[2333333],vis[2333333],top;
int ans[2333333];
int main()
{
	ios_base::sync_with_stdio(false);
	int n;
	cin>>n;
	if(n%4==2||n%4==3)
	{
		cout<<-1<<endl;
		return 0;
	}
	if(n==1)
	{
		cout<<1<<endl;
		return 0;
	}
	if(n==4)
	{
		cout<<"7 2 3 1"<<endl;
		return 0;
	}
	if(n==8)
	{
		cout<<"8 1 13 11 2 4 5 6"<<endl;
		return 0;
	}
	if(n%4==0)
	{
		int k=n/4;
		for(int i=4*k;i>=2;i-=2)a[++top]=i;
		a[++top]=4*k-1;
		for(int i=2;i<=4*k;i+=2)a[++top]=i;
		a[++top]=2*k-1;
		for(int i=4*k-3;i>=2*k+1;i-=2)a[++top]=i;
		for(int i=2*k-3;i>=3;i-=2)a[++top]=i;
		a[++top]=4*k-1;
		a[++top]=2*k-1;
		for(int i=3;i<=2*k-3;i+=2)a[++top]=i;
		a[++top]=1;
		a[++top]=1;
		for(int i=2*k+1;i<=4*k-3;i+=2)a[++top]=i;
	}
	else
	{
		int k=n/4;
		a[++top]=4*k+1;
		for(int i=4*k-2;i>=2;i-=2)a[++top]=i;
		a[++top]=4*k;
		for(int i=2;i<=4*k-2;i+=2)a[++top]=i;
		a[++top]=2*k+1;
		for(int i=4*k+1;i>=2*k+3;i-=2)a[++top]=i;
		for(int i=2*k-1;i>=3;i-=2)a[++top]=i;
		a[++top]=4*k;
		a[++top]=2*k+1;
		for(int i=3;i<=2*k-1;i+=2)a[++top]=i;
		a[++top]=1;
		a[++top]=1;
		for(int i=2*k+3;i<=4*k-1;i+=2)a[++top]=i;
	}
	for(int i=1;i<=2*n;i++)
	{
//		cerr<<a[i]<<' ';
		if(!vis[a[i]])
		{
			ans[a[i]]=i;
			vis[a[i]]=1;
		}
	}
	cerr<<endl;
	for(int i=1;i<=n;i++)
	{
		cout<<ans[i]<<" \n"[i==n];
	}
	return 0;
}

  

I. Grammy and Ropes

#include<bits/stdc++.h>
using namespace std;
bool a[11],b[11];
string s[11];
int main()
{
	for(int i=1;i<=6;i++)cin>>s[i];
	for(int i=1;i<=6;i++)
	{
		if(s[i]=="true")a[i]=1;
		else a[i]=0;
	}
	int ans=7;
	for(int i=1;i<=3;i++)
	{
		ans-=(a[i]!=a[i+3]);
		b[i]=(a[i]==1);
	}
	b[2]^=1;
	if(ans==7&&!(b[1]==b[2]&&b[1]==b[3]))ans++;
	cout<<ans<<endl;
	return 0;
}

  

J. Grammy and Jewelry

#include<bits/stdc++.h>
#define ll long long
#define db long double
using namespace std;
 
inline void up(int &a,const int &b){ if(a<b)a=b; }
const int maxn = 6050;
 
int n,m,T;
int a[maxn];
vector<int>V[maxn];
 
int f[maxn],g[maxn];
queue<int>q;
 
int dp[maxn];
 
int main()
{
	ios_base::sync_with_stdio(false);
	
	cin>>n>>m>>T;
	for(int i=2;i<=n;i++) cin>>a[i];
	for(int i=1;i<=m;i++)
	{
		int x,y; cin>>x>>y;
		V[x].push_back(y),V[y].push_back(x);
	}
	
	for(int i=1;i<=n;i++) f[i]=-1;
	f[1]=0; q.push(1);
	while(!q.empty())
	{
		const int x=q.front(); q.pop();
		for(auto y:V[x]) if(f[y]==-1)
		{
			f[y]=f[x]+1;
			q.push(y);
		}
	}
	
	for(int i=1;i<=n;i++) if(f[i]!=-1)
		up(g[f[i]<<1],a[i]);
	dp[0]=0;
	for(int i=1;i<=T;i++)
	{
		for(int j=1;j<=i;j++) up(dp[i],dp[i-j]+g[j]);
	}
	
	for(int i=1;i<=T;i++) cout<<dp[i]<<' ';
	cout<<endl;
	
	return 0;
}

  

K. Grammy's Kingdom

#include<bits/stdc++.h>
#define rep(i,n) for(int i=1;i<=n;++i)
#define mp make_pair
#define pb push_back
#define st first
#define nd second
using namespace std;
using ll=long long;
using pr=pair<int,int>;
const int N=2e6+5,mod=998244353;
int inv[N];
 
int n,m;
bool is[N];
 
int cnt[N];
vector<int>b;
vector<pr>cb;
 
int S2[N];
int sol(int x,int y,int bg){
    //sig(f(l,r)) l<=x r<=y f(1,1)=to protect bg nodes
    bg=bg-1;
    //ret=ret+SS[bg-1]; bg<=1
    return ((S2[x+y+bg-1]-S2[y+bg-1]-S2[x+bg-1])%mod+mod)%mod;
}
int main(){
    scanf("%d%d",&n,&m);
 
    inv[1]=1;
    for(int i=2;i<=n+1;++i)
        inv[i]=((ll)mod-(mod/i))*inv[mod%i]%mod;
 
    rep(i,n)S2[i]=(ll)(n-i)*inv[i+1]%mod;//to protect i nodes
    rep(i,n)S2[i]=(S2[i]+S2[i-1])%mod;//1+...+i
    rep(i,n)S2[i]=(S2[i]+S2[i-1])%mod;//i*1+...+1*i
 
    rep(i,m){
        int x;
        scanf("%d",&x);
        is[x]=1;
    }
 
    is[n+1]=1;
    int la=0;
    //b = block
    rep(i,n+1)if(is[i])b.pb(i-la),++cnt[i-la],la=i;
    //bc = <size,cnt>
    rep(i,n)if(cnt[i]>0)cb.pb(mp(i,cnt[i]));
 
    int ans=0;
    int siz=cb.size();
    for(int i=0;i<siz;++i){
        //same sized
        //C(size,2)
        int X=((ll)cb[i].nd*(cb[i].nd-1)/2)%mod;
        ans=(ans+(ll)sol(cb[i].st,cb[i].st,2)*X)%mod;
        for(int j=i+1;j<siz;++j){
            //different sized
            int X=(ll)cb[i].nd*cb[j].nd%mod;
            ans=(ans+(ll)sol(cb[i].st,cb[j].st,2)*X)%mod;
        }
    }
    //adjacent blocks act differently
    siz=b.size();
    for(int i=0;i+1<siz;++i)
        ans=((ll)ans-sol(b[i],b[i+1],2)+sol(b[i],b[i+1],1)+mod)%mod;
    //inside a block
    for(int i=0;i<siz;++i)
        ans=(ans+S2[b[i]-1])%mod;
 
    printf("%d\n",ans);
    return 0;
}

  

L. String Freshman

#include<cstdio>
int n,i;char a[100005];
int main(){
  scanf("%d%s",&n,a+1);
  for(i=2;i<=n;i++)if(a[i]==a[1])return puts("Wrong Answer"),0;
  puts("Correct");
}

  

M. Game Theory

#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(long long i=1;i<=n;++i)
#define mp make_pair
#define pb push_back
int main()
{
    puts("0.0000");
    return 0;
}