题目连接:传送门
B - Prefix Code
签到题,字符串hash、unordered_map、字典树都可以

1 #include<bits/stdc++.h> 2 /* 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<vector> 7 #include<cctype> 8 #include<queue> 9 #include<algorithm> 10 #include<map> 11 #include<set> 12 */ 13 #pragma GCC optimize(2) 14 using namespace std; 15 typedef long long LL; 16 typedef pair<int,int> pii; 17 typedef pair<double,double> pdd; 18 const int N=2e4+5; 19 const int M=3005; 20 const int inf=0x3f3f3f3f; 21 const LL mod=1e9+7; 22 const double eps=1e-9; 23 const long double pi=acos(-1.0L); 24 #define ls (i<<1) 25 #define rs (i<<1|1) 26 #define fi first 27 #define se second 28 #define pb push_back 29 #define mk make_pair 30 #define mem(a,b) memset(a,b,sizeof(a)) 31 LL read() 32 { 33 LL x=0,t=1; 34 char ch; 35 while(!isdigit(ch=getchar())) if(ch=='-') t=-1; 36 while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); } 37 return x*t; 38 } 39 unordered_map<string,int> mp; 40 char a[N][15]; 41 int main() 42 { 43 int T=read(),test=0; 44 while(T--) 45 { 46 int n=read(); 47 for(int i=1;i<=n;i++) 48 { 49 scanf("%s",a[i]); 50 char s[15]; 51 mem(s,0); 52 int l=strlen(a[i]); 53 for(int j=0;j<l;j++) 54 s[j]=a[i][j],mp[s]++; 55 } 56 int ans=0; 57 for(int i=1;i<=n;i++) 58 if(mp[a[i]]>1) { 59 ans=1; 60 break; 61 } 62 printf("Case #%d: ",++test); 63 if(!ans) printf("Yes "); 64 else printf("No "); 65 mp.clear(); 66 } 67 return 0; 68 }
D - Spanning Tree Removal
构造题。第i棵树,按 i , i+1 , i-1 , i+2 , i-2 , i+3 .... 注意取模

1 #include<bits/stdc++.h> 2 /* 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<vector> 7 #include<cctype> 8 #include<queue> 9 #include<algorithm> 10 #include<map> 11 #include<set> 12 */ 13 #pragma GCC optimize(2) 14 using namespace std; 15 typedef long long LL; 16 typedef pair<int,int> pii; 17 typedef pair<double,double> pdd; 18 const int N=2e3+5; 19 const int M=3005; 20 const int inf=0x3f3f3f3f; 21 const LL mod=1e9+7; 22 const double eps=1e-9; 23 const long double pi=acos(-1.0L); 24 #define ls (i<<1) 25 #define rs (i<<1|1) 26 #define fi first 27 #define se second 28 #define pb push_back 29 #define mk make_pair 30 #define mem(a,b) memset(a,b,sizeof(a)) 31 LL read() 32 { 33 LL x=0,t=1; 34 char ch; 35 while(!isdigit(ch=getchar())) if(ch=='-') t=-1; 36 while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); } 37 return x*t; 38 } 39 40 int main() 41 { 42 int T=read(),test=0; 43 while(T--) 44 { 45 int n=read(); 46 printf("Case #%d: %d ",++test,n/2); 47 for(int i=1;i<=n/2;i++) 48 { 49 int t=1,x=i-1; 50 for(int j=1;j<n;j++) 51 { 52 int y=(x+t*j+n)%n; 53 printf("%d %d ",x+1,y+1); 54 x=y; 55 t*=-1; 56 } 57 } 58 } 59 return 0; 60 }
E - Cave Escape
模拟生成矩阵,再建边求最大生成树(kruskal + 桶排序 ,据说快排会被卡)

1 #include<bits/stdc++.h> 2 /* 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<vector> 7 #include<cctype> 8 #include<queue> 9 #include<algorithm> 10 #include<map> 11 #include<set> 12 */ 13 #pragma GCC optimize(2) 14 using namespace std; 15 typedef long long LL; 16 typedef pair<int,int> pii; 17 typedef pair<double,double> pdd; 18 const int N=1e3+5; 19 const int M=1e4+5; 20 const int inf=0x3f3f3f3f; 21 const LL mod=1e9+7; 22 const double eps=1e-9; 23 const long double pi=acos(-1.0L); 24 #define ls (i<<1) 25 #define rs (i<<1|1) 26 #define fi first 27 #define se second 28 #define pb push_back 29 #define mk make_pair 30 #define mem(a,b) memset(a,b,sizeof(a)) 31 LL read() 32 { 33 LL x=0,t=1; 34 char ch; 35 while(!isdigit(ch=getchar())) if(ch=='-') t=-1; 36 while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); } 37 return x*t; 38 } 39 int n,m,sx,sy,ex,ey,x1,x2,x3,a,b,c,p; 40 int v[N][N],f[N*N]; 41 vector<pii> w[M]; 42 int getf(int x) 43 { 44 return x==f[x]?f[x]:f[x]=getf(f[x]); 45 } 46 int main() 47 { 48 int T=read(),test=0; 49 while(T--) 50 { 51 scanf("%d%d%d%d%d%d",&n,&m,&sx,&sy,&ex,&ey); 52 scanf("%d%d%d%d%d%d",&x1,&x2,&a,&b,&c,&p); 53 for(int i=1;i<=n*m;i++) f[i]=i; 54 for(int i=0;i<M;i++) w[i].clear(); 55 int cnt=1; 56 for(int i=1;i<=n;i++) 57 for(int j=1;j<=m;j++,cnt++) 58 if(cnt>=3) x3=(a*x2+b*x1+c)%p,v[i][j]=x3,x1=x2,x2=x3; 59 else if(cnt==2) v[i][j]=x2; 60 else v[i][j]=x1; 61 //for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) printf("%d%c",v[i][j],j==m?' ':' '); 62 for(int i=1;i<=n;i++) 63 for(int j=1;j<=m;j++){ 64 if(i<n) w[v[i][j]*v[i+1][j]].pb(mk((i-1)*m+j,i*m+j)); 65 if(j<m) w[v[i][j]*v[i][j+1]].pb(mk((i-1)*m+j,(i-1)*m+j+1)); 66 } 67 LL ans=0; 68 for(int i=10000;i>=0;i--) 69 { 70 for(auto x:w[i]) 71 { 72 int u=x.fi,v=x.se; 73 int fu=getf(u),fv=getf(v); 74 if(fu!=fv) f[fu]=fv,ans+=i; 75 } 76 } 77 printf("Case #%d: %lld ",++test,ans); 78 } 79 return 0; 80 }
H - Tree Partition
正着做不太容易,可以反过来考虑二分答案,check(x)时自底向上贪心。对于每个点u, 维护一个sum[u] (表示以 u 为根的树中,包含 u 的子树权值和且其权值和小于等于x );
贪心的话,则是 sum[u]+=sum[v] ,v是u的儿子结点;若sum[u] > x 了,意味着我必须要切割这棵树,但又要尽可能少切割,因此只需先切割大的sum[v](由于自底向上,sum[v]一定小等于x),直到sum[u]<=x;

#include<bits/stdc++.h> /* #include<cstdio> #include<cmath> #include<cstring> #include<vector> #include<cctype> #include<queue> #include<algorithm> #include<map> #include<set> */ #pragma GCC optimize(2) using namespace std; typedef long long LL; typedef pair<int,int> pii; typedef pair<double,double> pdd; const int N=2e5+5; const int M=3005; const int inf=0x3f3f3f3f; const LL mod=1e9+7; const double eps=1e-9; const long double pi=acos(-1.0L); #define ls (i<<1) #define rs (i<<1|1) #define fi first #define se second #define pb push_back #define mk make_pair #define mem(a,b) memset(a,b,sizeof(a)) LL read() { LL x=0,t=1; char ch; while(!isdigit(ch=getchar())) if(ch=='-') t=-1; while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); } return x*t; } LL w[N],sum[N]; int cnt; vector<int> e[N]; void dfs(int u,int pre,LL k) { sum[u]=w[u]; vector<LL> a; for(auto v:e[u]) { if(v==pre) continue; dfs(v,u,k); sum[u]+=sum[v]; a.pb(sum[v]); } sort(a.begin(),a.end()); int p=a.size(); while(sum[u]>k) sum[u]-=a[--p],cnt++; } int main() { int T=read(),test=0; while(T--) { int n=read(),k=read(); for(int i=1;i<n;i++) { int x=read(),y=read(); e[x].pb(y); e[y].pb(x); } LL l=0,r=0; for(int i=1;i<=n;i++) w[i]=read(),l=max(l,w[i]),r+=w[i]; while(l<=r) { LL mid=l+r>>1; cnt=0; dfs(1,0,mid); //printf("cnt = %d,mid = %d ",cnt,mid); if(cnt<k) r=mid-1; else l=mid+1; } printf("Case #%d: %lld ",++test,l); for(int i=1;i<=n;i++) e[i].clear(); } return 0; }
F - A Simple Problem On A Tree
贼恶心的一个大树剖,写了两遍才过。为了简化代码,写了很多函数;操作1 区间赋值w 可以直接写,但也可以转化成 乘以0 再加上w。
其中需要注意,立方和、平方和、一次幂和的更新顺序;还有延时标记的初始化

1 #include<bits/stdc++.h> 2 /* 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<vector> 7 #include<cctype> 8 #include<queue> 9 #include<algorithm> 10 #include<map> 11 #include<set> 12 */ 13 #pragma GCC optimize(2) 14 using namespace std; 15 typedef long long LL; 16 typedef pair<int,int> pii; 17 typedef pair<double,double> pdd; 18 const int N=2e5+5; 19 const int M=3005; 20 const int inf=0x3f3f3f3f; 21 const LL mod=1e9+7; 22 const double eps=1e-9; 23 const long double pi=acos(-1.0L); 24 #define ls (i<<1) 25 #define rs (i<<1|1) 26 #define fi first 27 #define se second 28 #define pb push_back 29 #define mk make_pair 30 #define mem(a,b) memset(a,b,sizeof(a)) 31 LL read() 32 { 33 LL x=0,t=1; 34 char ch; 35 while(!isdigit(ch=getchar())) if(ch=='-') t=-1; 36 while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); } 37 return x*t; 38 } 39 LL lazy1[N<<2],lazy2[N<<2]; 40 int deep[N],id[N],top[N],f[N],cnt[N],son[N],tot,n,m,a[N],rk[N]; 41 vector<int> e[N]; 42 struct node{ LL x,y,z; }c[N<<2]; 43 void dfs(int u,int pre) 44 { 45 f[u]=pre; 46 cnt[u]=1; 47 deep[u]=deep[pre]+1; 48 for(auto v:e[u]) 49 { 50 if(v==pre) continue; 51 dfs(v,u); 52 cnt[u]+=cnt[v]; 53 if(cnt[son[u]]<cnt[v]) son[u]=v; 54 } 55 } 56 void dfs2(int u,int pre,int t) 57 { 58 top[u]=t; 59 id[u]=++tot; 60 rk[tot]=u; 61 if(son[u]) dfs2(son[u],u,t); 62 for(auto v:e[u]) 63 if(v!=son[u]&&v!=pre) dfs2(v,u,v); 64 } 65 inline LL s2(LL x) 66 { 67 return x*x%mod; 68 } 69 inline LL s3(LL x) 70 { 71 return x*x%mod*x%mod; 72 } 73 void calmul(int i,LL w) 74 { 75 c[i].x=c[i].x*w%mod; 76 c[i].y=c[i].y*s2(w)%mod; 77 c[i].z=c[i].z*s3(w)%mod; 78 lazy1[i]=lazy1[i]*w%mod; 79 lazy2[i]=lazy2[i]*w%mod; 80 } 81 void caladd(int i,LL len,LL w) 82 { 83 c[i].z=(c[i].z+len*s3(w)%mod+3LL*s2(w)%mod*c[i].x+3LL*w%mod*c[i].y%mod )%mod; 84 c[i].y=(c[i].y+len*s2(w)%mod+2LL*w%mod*c[i].x%mod )%mod; 85 c[i].x=(c[i].x+len*w%mod )%mod; 86 lazy2[i]=(lazy2[i]+w)%mod; 87 } 88 void pushup(int i) 89 { 90 c[i].x=(c[ls].x+c[rs].x)%mod; 91 c[i].y=(c[ls].y+c[rs].y)%mod; 92 c[i].z=(c[ls].z+c[rs].z)%mod; 93 } 94 void pushdown(int i,int l,int r) 95 { 96 int mid=l+r>>1; 97 calmul(ls,lazy1[i]); 98 calmul(rs,lazy1[i]); 99 caladd(ls,mid-l+1,lazy2[i]); 100 caladd(rs,r-mid,lazy2[i]); 101 lazy1[i]=1; 102 lazy2[i]=0; 103 } 104 void build(int i,int l,int r) 105 { 106 lazy1[i]=1; 107 lazy2[i]=0; 108 if(l==r) 109 { 110 LL t=a[rk[l]]; 111 c[i].x=t; 112 c[i].y=s2(t); 113 c[i].z=s3(t); 114 return ; 115 } 116 int mid=l+r>>1; 117 build(ls,l,mid); 118 build(rs,mid+1,r); 119 pushup(i); 120 } 121 void update(int i,int l,int r,int ll,int rr,int flag,LL w) 122 { 123 if(ll<=l&&r<=rr) 124 { 125 if(flag==1) 126 { 127 LL len=r-l+1; 128 lazy1[i]=0; 129 lazy2[i]=w; 130 c[i].x=w*len%mod; 131 c[i].y=s2(w)*len%mod; 132 c[i].z=s3(w)*len%mod; 133 } 134 else if(flag==2) caladd(i,r-l+1,w); 135 else calmul(i,w); 136 return ; 137 } 138 pushdown(i,l,r); 139 int mid=l+r>>1; 140 if(mid>=ll) update(ls,l,mid,ll,rr,flag,w); 141 if(mid<rr) update(rs,mid+1,r,ll,rr,flag,w); 142 pushup(i); 143 } 144 LL query(int i,int l,int r,int ll,int rr) 145 { 146 if(ll<=l&&r<=rr) return c[i].z; 147 pushdown(i,l,r); 148 LL t1=0,t2=0; 149 int mid=l+r>>1; 150 if(mid>=ll) t1=query(ls,l,mid,ll,rr); 151 if(mid<rr) t2=query(rs,mid+1,r,ll,rr); 152 return (t1+t2)%mod; 153 } 154 void change(int x,int y,int flag,LL w) 155 { 156 while(top[x]!=top[y]) 157 { 158 if(deep[top[x]]<deep[top[y]]) swap(x,y); 159 update(1,1,n,id[top[x]],id[x],flag,w); 160 x=f[top[x]]; 161 } 162 if(id[x]>id[y]) swap(x,y); 163 update(1,1,n,id[x],id[y],flag,w); 164 } 165 LL getans(int x,int y) 166 { 167 LL ans=0; 168 while(top[x]!=top[y]) 169 { 170 if(deep[top[x]]<deep[top[y]]) swap(x,y); 171 ans+=query(1,1,n,id[top[x]],id[x]); 172 ans%=mod; 173 x=f[top[x]]; 174 } 175 if(id[x]>id[y]) swap(x,y); 176 ans+=query(1,1,n,id[x],id[y]); 177 ans%=mod; 178 return ans; 179 } 180 inline void init() 181 { 182 tot=0; 183 mem(son,0); 184 for(int i=1;i<=n;i++) e[i].clear(); 185 } 186 int main() 187 { 188 int T=read(),test=0; 189 while(T--) 190 { 191 n=read(); 192 for(int i=1;i<n;i++) 193 { 194 int x=read(),y=read(); 195 e[x].pb(y); 196 e[y].pb(x); 197 } 198 for(int i=1;i<=n;i++) a[i]=read(); 199 dfs(1,0); 200 dfs2(1,0,1); 201 build(1,1,n); 202 m=read(); 203 printf("Case #%d: ",++test); 204 while(m--) 205 { 206 int cmd=read(),u=read(),v=read(); 207 if(cmd==4) printf("%lld ",getans(u,v)); 208 else 209 { 210 LL w=read(); 211 change(u,v,cmd,w); 212 } 213 } 214 init(); 215 } 216 return 0; 217 }
K - Color Graph
考虑到题目要求不能存在奇数环(简单环),而二分图正好满足要求,那么就二进制枚举二分图,再去掉同一集合的边即可,对于每一次枚举得到的ans 取最大。

1 #include<bits/stdc++.h> 2 /* 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<vector> 7 #include<cctype> 8 #include<queue> 9 #include<algorithm> 10 #include<map> 11 #include<set> 12 */ 13 #pragma GCC optimize(2) 14 using namespace std; 15 typedef long long LL; 16 typedef pair<int,int> pii; 17 typedef pair<double,double> pdd; 18 const int N=2e5+5; 19 const int M=3005; 20 const int inf=0x3f3f3f3f; 21 const LL mod=1e9+7; 22 const double eps=1e-9; 23 const long double pi=acos(-1.0L); 24 #define ls (i<<1) 25 #define rs (i<<1|1) 26 #define fi first 27 #define se second 28 #define pb push_back 29 #define mk make_pair 30 #define mem(a,b) memset(a,b,sizeof(a)) 31 LL read() 32 { 33 LL x=0,t=1; 34 char ch; 35 while(!isdigit(ch=getchar())) if(ch=='-') t=-1; 36 while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); } 37 return x*t; 38 } 39 LL lazy1[N<<2],lazy2[N<<2]; 40 int deep[N],id[N],top[N],f[N],cnt[N],son[N],tot,n,m,a[N],rk[N]; 41 vector<int> e[N]; 42 struct node{ LL x,y,z; }c[N<<2]; 43 void dfs(int u,int pre) 44 { 45 f[u]=pre; 46 cnt[u]=1; 47 deep[u]=deep[pre]+1; 48 for(auto v:e[u]) 49 { 50 if(v==pre) continue; 51 dfs(v,u); 52 cnt[u]+=cnt[v]; 53 if(cnt[son[u]]<cnt[v]) son[u]=v; 54 } 55 } 56 void dfs2(int u,int pre,int t) 57 { 58 top[u]=t; 59 id[u]=++tot; 60 rk[tot]=u; 61 if(son[u]) dfs2(son[u],u,t); 62 for(auto v:e[u]) 63 if(v!=son[u]&&v!=pre) dfs2(v,u,v); 64 } 65 inline LL s2(LL x) 66 { 67 return x*x%mod; 68 } 69 inline LL s3(LL x) 70 { 71 return x*x%mod*x%mod; 72 } 73 void calmul(int i,LL w) 74 { 75 c[i].x=c[i].x*w%mod; 76 c[i].y=c[i].y*s2(w)%mod; 77 c[i].z=c[i].z*s3(w)%mod; 78 lazy1[i]=lazy1[i]*w%mod; 79 lazy2[i]=lazy2[i]*w%mod; 80 } 81 void caladd(int i,LL len,LL w) 82 { 83 c[i].z=(c[i].z+len*s3(w)%mod+3LL*s2(w)%mod*c[i].x+3LL*w%mod*c[i].y%mod )%mod; 84 c[i].y=(c[i].y+len*s2(w)%mod+2LL*w%mod*c[i].x%mod )%mod; 85 c[i].x=(c[i].x+len*w%mod )%mod; 86 lazy2[i]=(lazy2[i]+w)%mod; 87 } 88 void pushup(int i) 89 { 90 c[i].x=(c[ls].x+c[rs].x)%mod; 91 c[i].y=(c[ls].y+c[rs].y)%mod; 92 c[i].z=(c[ls].z+c[rs].z)%mod; 93 } 94 void pushdown(int i,int l,int r) 95 { 96 int mid=l+r>>1; 97 calmul(ls,lazy1[i]); 98 calmul(rs,lazy1[i]); 99 caladd(ls,mid-l+1,lazy2[i]); 100 caladd(rs,r-mid,lazy2[i]); 101 lazy1[i]=1; 102 lazy2[i]=0; 103 } 104 void build(int i,int l,int r) 105 { 106 lazy1[i]=1; 107 lazy2[i]=0; 108 if(l==r) 109 { 110 LL t=a[rk[l]]; 111 c[i].x=t; 112 c[i].y=s2(t); 113 c[i].z=s3(t); 114 return ; 115 } 116 int mid=l+r>>1; 117 build(ls,l,mid); 118 build(rs,mid+1,r); 119 pushup(i); 120 } 121 void update(int i,int l,int r,int ll,int rr,int flag,LL w) 122 { 123 if(ll<=l&&r<=rr) 124 { 125 if(flag==1) 126 { 127 LL len=r-l+1; 128 lazy1[i]=0; 129 lazy2[i]=w; 130 c[i].x=w*len%mod; 131 c[i].y=s2(w)*len%mod; 132 c[i].z=s3(w)*len%mod; 133 } 134 else if(flag==2) caladd(i,r-l+1,w); 135 else calmul(i,w); 136 return ; 137 } 138 pushdown(i,l,r); 139 int mid=l+r>>1; 140 if(mid>=ll) update(ls,l,mid,ll,rr,flag,w); 141 if(mid<rr) update(rs,mid+1,r,ll,rr,flag,w); 142 pushup(i); 143 } 144 LL query(int i,int l,int r,int ll,int rr) 145 { 146 if(ll<=l&&r<=rr) return c[i].z; 147 pushdown(i,l,r); 148 LL t1=0,t2=0; 149 int mid=l+r>>1; 150 if(mid>=ll) t1=query(ls,l,mid,ll,rr); 151 if(mid<rr) t2=query(rs,mid+1,r,ll,rr); 152 return (t1+t2)%mod; 153 } 154 void change(int x,int y,int flag,LL w) 155 { 156 while(top[x]!=top[y]) 157 { 158 if(deep[top[x]]<deep[top[y]]) swap(x,y); 159 update(1,1,n,id[top[x]],id[x],flag,w); 160 x=f[top[x]]; 161 } 162 if(id[x]>id[y]) swap(x,y); 163 update(1,1,n,id[x],id[y],flag,w); 164 } 165 LL getans(int x,int y) 166 { 167 LL ans=0; 168 while(top[x]!=top[y]) 169 { 170 if(deep[top[x]]<deep[top[y]]) swap(x,y); 171 ans+=query(1,1,n,id[top[x]],id[x]); 172 ans%=mod; 173 x=f[top[x]]; 174 } 175 if(id[x]>id[y]) swap(x,y); 176 ans+=query(1,1,n,id[x],id[y]); 177 ans%=mod; 178 return ans; 179 } 180 inline void init() 181 { 182 tot=0; 183 mem(son,0); 184 for(int i=1;i<=n;i++) e[i].clear(); 185 } 186 int main() 187 { 188 int T=read(),test=0; 189 while(T--) 190 { 191 n=read(); 192 for(int i=1;i<n;i++) 193 { 194 int x=read(),y=read(); 195 e[x].pb(y); 196 e[y].pb(x); 197 } 198 for(int i=1;i<=n;i++) a[i]=read(); 199 dfs(1,0); 200 dfs2(1,0,1); 201 build(1,1,n); 202 m=read(); 203 printf("Case #%d: ",++test); 204 while(m--) 205 { 206 int cmd=read(),u=read(),v=read(); 207 if(cmd==4) printf("%lld ",getans(u,v)); 208 else 209 { 210 LL w=read(); 211 change(u,v,cmd,w); 212 } 213 } 214 init(); 215 } 216 return 0; 217 }