2019 ICPC南昌邀请赛网络赛比赛过程及题解
解题过程
中午吃饭比较晚,到机房lfw开始发各队的账号密码,byf开始读D题,shl电脑卡的要死,启动中...然后听到谁说A题过了好多,然后shl让blf读A题,A题blf一下就A了。然后lfw读完M题(shl的电脑终于打开了,然后输入密码,密码错误。。。自闭),说AC 自动机板题,然后找板子,,,突然发现自己读错题目。后来不知道怎么A的。shl copy了一遍密码终于登上账号。然后lfw一个人用单调栈和前缀和st表A掉了I题;byf 秒了H题;
shl和byf读j题,读完吧题意告诉lfw,lfw说水题,然后树链剖分加线段树离线就过了。同时byf在想K题,然后推出式子,利用前缀和就过了(听说好多对TLE了,应该没用前缀和维护);然后还有一个多小时,,,shl和byf看D题,lfw看C题,然后shl和byf没啥想法,lfw调C调了一万年,最后也没过。。。这场每一题都是一下就过了,罚时较少。(这场shl全场OB,没碰键盘,状态极差...)
C题要注意一下,java 的BigInteger运算比c++用数组模拟高精度快,lfw被卡住了,c++要几分钟预处理,java几乎1s出来,所以最后用java,但是看错题没看到要字典序最小,没时间改
第二天改好了,最后java也超时。。。要矩阵乘法预处理出28个数。。。
题解
先放代码,题解后面更新。
A. PERFECT NUMBER PROBLEM
#include<bits/stdc++.h> using namespace std; int main() { printf("6\n"); printf("28\n"); printf("496\n"); printf("8128\n"); printf("33550336\n"); return 0; }
B. Greedy HOUHO
Unsolved.
C. Angry FFF Party
Unsolved.
lfw的题解链接 https://blog.csdn.net/liufengwei1/article/details/89522815
import java.lang.reflect.Array; import java.util.*; import java.math.*; import java.io.FileOutputStream; import java.io.PrintStream; public class Main { public static BigInteger[][] multi(BigInteger [][]a,BigInteger [][]b) { BigInteger [][]c= new BigInteger[3][3]; for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) c[i][j]=BigInteger.ZERO; for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) for(int k=1;k<=2;k++) { c[i][k] = c[i][k].add(a[i][j].multiply(b[j][k])); } return c; } public static BigInteger qp(int b) { BigInteger ans[][]=new BigInteger[3][3]; BigInteger cnt[][]=new BigInteger[3][3]; ans[1][1]=BigInteger.ONE;ans[1][2]=BigInteger.ZERO; ans[2][1]=BigInteger.ZERO;ans[2][2]=BigInteger.ONE; cnt[1][1]=BigInteger.ZERO;cnt[1][2]=BigInteger.ONE; cnt[2][1]=BigInteger.ONE;cnt[2][2]=BigInteger.ONE; while(b>0) { if(b%2==1) ans=multi(ans,cnt); cnt=multi(cnt,cnt); b>>=1; } return ans[2][2]; } public static void main(String args[]) { int []f=new int [100]; int []ans=new int[100]; int up=0,cnt=3; f[1]=1;f[2]=1; for(int i=3;i<=28;i++) f[i] = f[i - 2] + f[i - 1]; //PrintStream ps=new PrintStream("B."); BigInteger []num=new BigInteger[30]; BigInteger a,b,w,sum=BigInteger.ZERO,tmp=BigInteger.ZERO; a=BigInteger.ONE; b=BigInteger.ONE; num[1]=BigInteger.ONE; num[2]=BigInteger.ONE; num[3]=BigInteger.ONE; Scanner input=new Scanner(System.in); int id=0; //System.out.println("a[1]=1;"); //System.out.println("a[2]=1;"); //System.out.println("a[3]=1;"); id=4; for(int i=4;i<=28;i++) num[i]=qp(f[i]-1); int t,anscnt; t=input.nextInt(); while(t>0) { t--;sum=BigInteger.ZERO; w=input.nextBigInteger(); anscnt=0; for(int i=28;i>=1;i--) { tmp=sum.add(num[i]); if(tmp.compareTo(w)<=0) { sum = tmp; ans[++anscnt] = i; } } if(sum.equals(w)) { if(ans[anscnt]==5) { ans[anscnt]=1;ans[++anscnt]=2;ans[++anscnt]=3; ans[++anscnt]=4; } else if(ans[anscnt]==4) { ans[anscnt]=1; ans[++anscnt]=2; } else if(ans[anscnt]==3) { if(ans[anscnt-1]==4) { ans[anscnt-1]=3; ans[anscnt]=1; ans[++anscnt]=2; } else ans[anscnt]=1; } else if(ans[anscnt]==2) { if(ans[anscnt-1]==3) { ans[anscnt - 1] = 1; ans[anscnt] = 2; } } Arrays.sort(ans,1,anscnt+1); for(int j=1;j<=anscnt;j++) { if(j>1) System.out.print(" "); System.out.print(ans[j]); } System.out.println(""); } else System.out.println("-1"); } } }
D. Match Stick Game
Unsolved.
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int INF=0x3f3f3f3f; const int num[10]={6,2,5,5,4,5,6,3,7,6}; ll f[2][15][75]; inline void init() { for (int i=0;i<15;i++) for (int j=0;j<75;j++) f[1][i][j]=-1e10;//max memset(f[0],INF,sizeof(f[0]));//min f[0][0][0]=0; f[1][0][0]=0; for (int i=1;i<=10;i++) for (int j=1;j<=i*7;j++) for (int k=0;k<=9;k++) { if(j<num[k]) continue; f[0][i][j]=min(f[0][i][j],f[0][i-1][j-num[k]]*10+k); f[1][i][j]=max(f[1][i][j],f[1][i-1][j-num[k]]*10+k); } } ll dp[105][705]; char s[105]; int nums[105]; int main() { init(); int T,n; scanf("%d",&T); while(T--) { int tot=0; scanf("%d%s",&n,s); for(int i=0;i<=n;i++) for(int j=0;j<=n*7;j++) dp[i][j]=-1e12;//dao di i kuai haisheng j gen de max int last=-1,cnt=0; for(int i=0;s[i];++i)//tongji mubang de numbers { if(s[i]=='+'||s[i]=='-') { nums[cnt++]=i-last-1; last=i; } if(s[i]=='+') tot+=2; else if(s[i]=='-') tot+=1; else tot+=num[s[i]-'0']; } nums[cnt++]=strlen(s)-1-last; for(int i=1;i<=min(nums[0]*7,tot);++i) dp[0][tot-i]=max(dp[0][tot-i],f[1][nums[0]][i]); for(int i=1;i<cnt;++i) for(int j=0;j<=tot;++j) for(int k=2;k<=min(nums[i]*7+2,j);++k) { dp[i][j-k]=max(dp[i][j-k],dp[i-1][j]-f[0][nums[i]][k-1]);//- dp[i][j-k]=max(dp[i][j-k],dp[i-1][j]+f[1][nums[i]][k-2]);//+ } printf("%lld\n",dp[cnt-1][0]); } return 0; }
E. Card Game
Unsolve.
F. Information Transmitting
Unsolved.
G. tsy's number
byf题解 南昌网络赛tsy's number(莫比乌斯反演&线性递推)
H. Coloring Game
#include<bits/stdc++.h> #define int long long using namespace std; const int mod=1e9+7; int quick_pow(int a,int b) { int ans=1; while(b) { if(b&1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } int32_t main() { int n; scanf("%lld",&n); if(n==1) {printf("1\n");return 0;} printf("%lld\n",2*2*quick_pow(3,n-2)%mod); return 0; }
I. Max answer
#include<bits/stdc++.h> #define maxl 500010 using namespace std; int n,top,lg; long long ans=0; long long s[maxl]; long long a[maxl],sum[maxl],dol[maxl],dor[maxl]; long long mini[20][maxl],mx[20][maxl]; map <long long,int> mp; map <long long,int> :: iterator it; inline void prework() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]),sum[i]=sum[i-1]+a[i]; top=0;int l=0,r=0; while(l<=n && r<=n) { while(a[l]<=0 && l<=n) l++; if(a[l]>0) { r=l; while(a[r+1]>0) r++; top=0;s[0]=l-1; for(int i=l;i<=r;i++) { while(top>0 && a[i]<a[s[top]]) { dor[s[top]]=i; top--; } s[++top]=i;dol[i]=s[top-1]; } while(top>0) dor[s[top]]=r+1,top--; for(int i=l;i<=r;i++) ans=max(ans,(sum[dor[i]-1]-sum[dol[i]])*a[i]); } else r=l; l=r+1; } } inline void mainwork() { int lg=log2(n),t; for(int i=0;i<=n;i++) mx[0][i]=mini[0][i]=sum[i]; for(int i=1;i<=lg;i++) for(int j=0;j<=n;j++) { mx[i][j]=max(mx[i-1][j],mx[i-1][j+(1<<(i-1))]); mini[i][j]=min(mini[i-1][j],mini[i-1][j+(1<<(i-1))]); } long long mxx,mii; for(int i=1;i<=n;i++) if(a[i]<0) { t=log2(i-0+1); mxx=max(mx[t][0],mx[t][i-(1<<t)+1]); t=log2(n-i+1); mii=min(mini[t][i],mini[t][n-(1<<t)+1]); ans=max((mii-mxx)*a[i],ans); } } inline void print() { printf("%lld",ans); } int main() { prework(); mainwork(); print(); return 0; }
J. Distance on the tree
#include<bits/stdc++.h> #define maxl 200010 #define inf 2000000001 using namespace std; int n,nn,q,cnt=0,nodecnt=0,num=0; int a[maxl],dep[maxl],tot[maxl],son[maxl],top[maxl],fa[maxl],ehead[maxl]; int idx[maxl],dy[maxl],ans[maxl]; struct ed { int to,nxt; }e[maxl<<1]; struct node { int l,r,sum; }tree[maxl<<2]; struct qu { int u,v,w,id; }que[maxl],edg[maxl<<1]; char ch[maxl]; inline void adde(int u,int v) { e[++cnt].to=v;e[cnt].nxt=ehead[u];ehead[u]=cnt; } void dfs1(int u,int f) { int v; dep[u]=dep[f]+1;fa[u]=f;tot[u]=1; for(int i=ehead[u];i;i=e[i].nxt) { v=e[i].to; if(v==f) continue; dfs1(v,u); tot[u]+=tot[v]; if(tot[v]>tot[son[u]]) son[u]=v; } } void dfs2(int u,int topf) { int v; idx[u]=++nodecnt;dy[nodecnt]=u; top[u]=topf; if(!son[u]) return; dfs2(son[u],topf); for(int i=ehead[u];i;i=e[i].nxt) { v=e[i].to; if(idx[v]) continue; dfs2(v,v); } } void build(int k,int l,int r) { tree[k].l=l;tree[k].r=r; if(l==r) { tree[k].sum=0; return; } int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum; } inline bool cmp(const qu &x,const qu &y) { return x.w<y.w; } inline void prework() { scanf("%d%d",&n,&q); int u,v,w;num=n; nn=n; for(int i=1;i<=n-1;i++) { scanf("%d%d%d",&u,&v,&w); num++;edg[i]=qu{u,v,w,num}; adde(u,num);adde(num,v); adde(v,num);adde(num,u); } for(int i=1;i<=q;i++) { scanf("%d%d%d",&que[i].u,&que[i].v,&que[i].w); que[i].id=i;; } sort(edg+1,edg+1+n-1,cmp); sort(que+1,que+1+q,cmp); n=num; dfs1(1,0); dfs2(1,1); build(1,1,n); } void add(int k,int l) { if(tree[k].l==tree[k].r) { tree[k].sum++; return; } int mid=(tree[k].l+tree[k].r)>>1; if(l<=mid) add(k<<1,l); else add(k<<1|1,l); tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum; } int getsum(int k,int l,int r) { if(tree[k].l==l && tree[k].r==r) return tree[k].sum; int mid=(tree[k].l+tree[k].r)>>1; if(l>mid) return getsum(k<<1|1,l,r); else if(r<=mid) return getsum(k<<1,l,r); else return getsum(k<<1,l,mid)+getsum(k<<1|1,mid+1,r); } inline int gettreesum(int x,int y) { int ans=0; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); ans+=getsum(1,idx[top[x]],idx[x]); x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); ans+=getsum(1,idx[x],idx[y]); return ans; //printf("%d\n",ans); } inline void mainwork() { //int x,y; /*scanf("%d",&q); for(int i=1;i<=q;i++) { scanf("%s",ch); scanf("%d%d",&x,&y); if(ch[0]=='C') { a[x]=y; add(1,idx[x]); } else if(ch[1]=='S') gettreesum(x,y); else gettreemax(x,y); }*/ int edind=0; for(int i=1;i<=q;i++) { while(edind<nn-1 && edg[edind+1].w<=que[i].w) ++edind,add(1,idx[edg[edind].id]); ans[que[i].id]=gettreesum(que[i].u,que[i].v); } } inline void print() { for(int i=1;i<=q;i++) printf("%d\n",ans[i]); } int main() { prework(); mainwork(); print(); return 0; }
K. MORE XOR
#include<bits/stdc++.h> using namespace std; const int size=1e5+5; #define int long long int sum[4][size]; int arr[size]; int32_t main() { int t; scanf("%lld",&t); int n; while(t--) { scanf("%lld",&n); memset(sum,0,sizeof(sum)); for(int i=1;i<=n;i++) { scanf("%lld",&arr[i]); } for(int i=1;i<=n;i++) { for(int j=0;j<=3;j++) { sum[j][i]=sum[j][i-1]; } sum[i%4][i]=sum[i%4][i]^arr[i]; } int q; scanf("%lld",&q); int l,r; while(q--) { scanf("%lld%lld",&l,&r); int len=r-l+1; if(len%4==0) printf("0\n"); else if(len%4==1) { int b=l%4; printf("%lld\n",sum[b][l-1]^sum[b][r]); } else if(len%4==2) { int b=l%4,c=(l+1)%4; printf("%lld\n",sum[b][l-1]^sum[b][r]^sum[c][l-1]^sum[c][r]); } else if(len%4==3) { int c=(l+1)%4; printf("%lld\n",sum[c][l-1]^sum[c][r]); } } } return 0; }
L. qiqi'tree
Unsolved.
M. Subsequence
#include<bits/stdc++.h> #define maxl 100010 int slen,tlen,n; int nxt[maxl][27]; int nxtind[27]; char s[maxl],t[maxl]; inline void prework() { scanf("%s",s+1); slen=strlen(s+1); for(int i=0;i<26;i++) nxtind[i]=maxl-1; for(int i=slen;i>=1;i--) { for(int j=0;j<26;j++) nxt[i][j]=nxtind[j]; nxtind[s[i]-'a']=i; } for(int j=0;j<26;j++) nxt[0][j]=nxtind[j]; } inline bool check() { tlen=strlen(t+1); int u=0; for(int i=1;i<=tlen;i++) { u=nxt[u][t[i]-'a']; if(u==0 || u>slen) return false; } return true; } inline void mainwork() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",t+1); if(check()) puts("YES"); else puts("NO"); } } int main() { prework(); mainwork(); return 0; }
shl聚菜。%lfw.%byf.