2024“钉耙编程”中国大学生算法设计超级联赛(4)
题面:
https://files.cnblogs.com/files/clrs97/%E7%AC%AC%E5%9B%9B%E5%9C%BA%E9%A2%98%E9%9D%A2.pdf
题解:
https://files.cnblogs.com/files/clrs97/%E7%AC%AC%E5%9B%9B%E5%9C%BA%E9%A2%98%E8%A7%A3.pdf
Code:
A. 超维攻坚
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | #include<cstdio> const int N=15,inf=~0U>>1; int Case,n,i,j,k,S,o; bool ok[(1<<N)+1]; struct P{ int x,y,z; P(){} P( int _x, int _y, int _z){x=_x,y=_y,z=_z;} P operator-( const P&p) const { return P(x-p.x,y-p.y,z-p.z);} P operator*( const P&p) const { return P(y*p.z-z*p.y,z*p.x-x*p.z,x*p.y-y*p.x);} int operator^( const P&p) const { return x*p.x+y*p.y+z*p.z;} }p[N]; inline int ptoplane( const P&a, const P&b, const P&c, const P&p){ return ((b-a)*(c-a))^(p-a);} inline void umin( int &a, int b){a>b?(a=b):0;} inline void umax( int &a, int b){a<b?(a=b):0;} inline bool colinear( const P&a, const P&b, const P&p){ P t=(a-b)*(b-p); return !t.x&&!t.y&&!t.z; } inline int sgn( int x){ if (x>0) return 1; if (x<0) return -1; return 0; } //12v^4 inline bool check( const P&a, const P&b, const P&c, const P&p){ return (((b-a)*(c-a))^((b-a)*(p-a)))>=0; } struct Face{ P a,b,c; int sgn; bool inside( const P&p) const { return check(a,b,c,p)&&check(b,c,a,p)&&check(c,a,b,p); } }f[N*N*N]; int main(){ scanf ( "%d" ,&Case); while (Case--){ scanf ( "%d" ,&n); for (i=0;i<n;i++) scanf ( "%d%d%d" ,&p[i].x,&p[i].y,&p[i].z); for (i=1;i<1<<n;i++)ok[i]=0; for (S=1;S<1<<n;S++){ if (__builtin_popcount(S)<=1){ ok[S]=1; continue ; } int m=0; bool same=1; for (i=0;i<n;i++) if (S>>i&1) for (j=0;j<i;j++) if (S>>j&1) for (k=0;k<j;k++) if (S>>k&1){ if (colinear(p[i],p[j],p[k])) continue ; int l=inf,r=-inf; for (o=0;o<n;o++) if (S>>o&1){ int tmp=ptoplane(p[i],p[j],p[k],p[o]); umin(l,tmp); umax(r,tmp); } if (l<0&&r>0) continue ; if (l||r)same=0; f[m].a=p[i]; f[m].b=p[j]; f[m].c=p[k]; f[m].sgn=sgn(l)+sgn(r); m++; } int mask=S; if (!m){ //colinear int xl=inf,xr=-inf; int yl=inf,yr=-inf; int zl=inf,zr=-inf; int idl=n,idr=0; for (i=0;i<n;i++) if (S>>i&1){ umin(xl,p[i].x);umax(xr,p[i].x); umin(yl,p[i].y);umax(yr,p[i].y); umin(zl,p[i].z);umax(zr,p[i].z); umin(idl,i);umax(idr,i); } for (i=0;i<n;i++){ if (S>>i&1) continue ; if (!colinear(p[idl],p[idr],p[i])) continue ; if (p[i].x<xl||p[i].x>xr) continue ; if (p[i].y<yl||p[i].y>yr) continue ; if (p[i].z<zl||p[i].z>zr) continue ; mask|=1<<i; } } else if (same){ //just a face for (i=0;i<n;i++){ if (S>>i&1) continue ; if (ptoplane(f[0].a,f[0].b,f[0].c,p[i])) continue ; for (j=0;j<m;j++) if (f[j].inside(p[i])){ mask|=1<<i; break ; } } } else { for (i=0;i<n;i++){ if (S>>i&1) continue ; for (j=0;j<m;j++){ int tmp=sgn(ptoplane(f[j].a,f[j].b,f[j].c,p[i])); if (tmp&&tmp!=f[j].sgn) break ; } if (j==m)mask|=1<<i; } } ok[mask]=1; } int ans=0; for (i=1;i<1<<n;i++) if (ok[i])ans++; printf ( "%d\n" ,ans); } } |
B. 黑白边游戏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | #include<cstdio> #include<cstdlib> #include<algorithm> #include<map> #include<vector> using namespace std; typedef unsigned int U; typedef pair<U,U>P; const int N=9,K=6,M=13055,CNT=305,inf=~0U>>1; int a[CNT],b[CNT],f[CNT][M],perm[N],deg[N],d[N][N]; bool g[N][N];U minS; U two[N],w[N];P ident[N]; inline void umin( int &a, int b){a>b?(a=b):0;} inline void umax( int &a, int b){a<b?(a=b):0;} struct Info{ int n,m,tot,id[N][N],apsp[K][K][M]; map<U, int >T; U mask[M]; vector< int >adj[M]; void init( int _n){ int i,j,k,o,A,B; n=_n; for (i=0;i<n;i++) for (j=0;j<i;j++)id[i][j]=id[j][i]=m++; dfs(0); for (i=1;i<=tot;i++){ sort(adj[i].begin(),adj[i].end()); adj[i].erase(unique(adj[i].begin(),adj[i].end()),adj[i].end()); } int d[N][N]; for (A=1;A<K;A++) for (B=1;B<K;B++) for (o=1;o<=tot;o++){ U S=mask[o]; for (i=0;i<n;i++) for (j=0;j<i;j++)d[i][j]=d[j][i]=(S>>id[i][j]&1)?B:A; for (i=0;i<n;i++)d[i][i]=0; for (k=0;k<n;k++) for (i=0;i<n;i++) for (j=0;j<n;j++)umin(d[i][j],d[i][k]+d[k][j]); int sum=0; for (i=0;i<n;i++) for (j=0;j<n;j++)sum+=d[i][j]; apsp[A][B][o]=sum; } } void reorder( int x, int vis){ if (x==n){ U now=0; for ( int i=0;i<n;i++) for ( int j=0;j<i;j++) if (g[perm[i]][perm[j]])now|=1U<<id[i][j]; if (minS>now)minS=now; return ; } P mindeg(~0U>>1,0); for ( int i=0;i<n;i++) if (!(vis>>i&1)&&mindeg>ident[i])mindeg=ident[i]; for ( int i=0;i<n;i++) if (!(vis>>i&1)&&mindeg==ident[i]){ perm[x]=i; reorder(x+1,vis|(1<<i)); } } U adjust(U S){ int i,j; for (i=0;i<n;i++)deg[i]=0; for (i=0;i<n;i++) for (j=0;j<i;j++){ g[i][j]=g[j][i]=S>>id[i][j]&1; if (g[i][j])deg[i]++,deg[j]++; } for (i=0;i<n;i++){ two[i]=0; for (j=0;j<n;j++) if (g[i][j])two[i]+=w[deg[j]]; } for (i=0;i<n;i++)ident[i]=P(deg[i],two[i]); minS=~0U; int vis=0,cnt=0; for (i=0;i<n;i++) if (deg[i]==0){ vis|=1<<i; perm[cnt++]=i; } for (i=0;i<n;i++) if (deg[i]==n-1){ vis|=1<<i; perm[cnt++]=i; } reorder(cnt,vis); return minS; } int dfs(U S){ S=adjust(S); int &x=T[S]; if (x) return x; x=++tot; mask[tot]=S; for ( int i=0;i<m;i++) if (!(S>>i&1)){ int y=dfs(S^(1U<<i)); adj[x].emplace_back(y); adj[y].emplace_back(x); } return x; } void solve( int cnt){ for ( int j=1;j<=tot;j++)f[cnt+1][j]=0; for ( int i=cnt;i;i--){ int A=a[i],B=b[i]; for ( int j=1;j<=tot;j++){ int cur=-inf; for ( const auto &k:adj[j])umax(cur,apsp[A][B][k]-f[i+1][k]); f[i][j]=cur; } } printf ( "%d\n" ,f[1][1]); } }info[N]; int main(){ for ( int i=0;i<N;i++)w[i]=( rand ()<<15)^ rand (); for ( int i=2;i<=8;i++)info[i].init(i); int Case; scanf ( "%d" ,&Case); while (Case--){ int n,cnt; scanf ( "%d%d" ,&n,&cnt); for ( int i=1;i<=cnt;i++) scanf ( "%d%d" ,&a[i],&b[i]); info[n].solve(cnt); } } |
C. 最优 K 子段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #include<iostream> #include<algorithm> #include<set> using namespace std; typedef pair< int , int >P; const int N=200005; int Case,n,k,i,j,a[N]; bool vis[N],is_prime[N],OK; int L,R,MID,ANS; set<P>T; inline void ins( int sum, int ptr){ T.insert(P(sum,ptr)); } inline bool valid( int sum, int ptr){ for (set<P>::iterator it=T.begin();it!=T.end();it++){ if (sum-it->first<MID) return 0; if (is_prime[ptr-it->second]) return 1; } return 0; } inline bool check(){ for ( int cur=1,ptr=1;cur<=k;cur++){ if (ptr>n) return 0; T.clear(); ins(0,ptr-1); for ( int sum=0;;ptr++){ if (ptr>n) return 0; sum+=a[ptr]; if (valid(sum,ptr)){ ptr++; break ; } ins(sum,ptr); } } return 1; } int main(){ for (i=2;i<N;i++) if (!vis[i]){ is_prime[i]=1; for (j=i;j<N;j+=i)vis[j]=1; } ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while (Case--){ cin>>n>>k; L=R=OK=0; for (i=1;i<=n;i++){ cin>>a[i]; if (a[i]>0)R+=a[i]; else L+=a[i]; } while (L<=R){ MID=(L+R)/2; if (check()){ OK=1; ANS=MID; L=MID+1; } else R=MID-1; } if (OK)cout<<ANS<< "\n" ; else cout<< "impossible\n" ; } } |
D. 分组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #include<cstdio> #include<algorithm> using namespace std; const int N=21,M=10,LEN=(1<<M)+5; int Case,n,m,i,ans,val[N],w[LEN],q[LEN],at[LEN]; bool fl[N][LEN],fr[N][LEN]; inline bool cmp( int x, int y){ return w[x]<w[y];} inline void umin( int &a, int b){a>b?(a=b):0;} inline void umax( int &a, int b){a<b?(a=b):0;} void dfs( int x, int suml, int sumr){ if (x==n){ for ( int i=0,ml=-1,mr=-1;i<1<<m;i++){ int o=q[i]; if (fl[n][o]&&w[o]>=w[o^suml]){ umax(ml,w[o^suml]); if (~mr)umin(ans,w[o]-min(w[o^suml],mr)); } if (fr[n][o]&&w[o]>=w[o^sumr]){ umax(mr,w[o^sumr]); if (~ml)umin(ans,w[o]-min(w[o^sumr],ml)); } } return ; } int v=val[x]; for ( int i=0;i<1<<m;i++){ fl[x+1][i]=fl[x][i]|fl[x][i^v]; fr[x+1][i]=fr[x][i]; } dfs(x+1,suml^v,sumr); for ( int i=0;i<1<<m;i++){ fl[x+1][i]=fl[x][i]; fr[x+1][i]=fr[x][i]|fr[x][i^v]; } dfs(x+1,suml,sumr^v); } int main(){ scanf ( "%d" ,&Case); while (Case--){ scanf ( "%d%d" ,&n,&m); for (i=0;i<n;i++) scanf ( "%d" ,&val[i]); for (i=0;i<1<<m;i++) scanf ( "%d" ,&w[i]),q[i]=i; sort(q,q+(1<<m),cmp); for (i=0;i<1<<m;i++)at[q[i]]=i; for (i=0;i<1<<m;i++)fl[1][i]=fr[1][i]=0; fl[1][0]=fr[1][0]=1; fl[1][val[0]]=1; ans=~0U>>1; dfs(1,val[0],0); printf ( "%d\n" ,ans); } } |
E. 多层血条
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include<cstdio> const int N=805; int Case,n,m,hp,dmg,i,j; char f[N]; int main(){ scanf ( "%d" ,&Case); while (Case--){ scanf ( "%d%d%d%d" ,&n,&m,&hp,&dmg); for (i=0;i<m;i++)f[i]= ' ' ; int top=(hp-1)/m; int lim=(hp-1)%m; int col=top%5+ 'A' ; int nxt=(top+4)%5+ 'A' ; if (top) for (i=0;i<m;i++)f[i]=nxt; for (i=0;i<=lim;i++)f[i]=col; if (dmg>m)dmg=m; while (dmg--){ f[lim]= '.' ; lim=(lim+m-1)%m; } putchar ( '+' ); for (i=0;i<m;i++) putchar ( '-' ); puts ( "+" ); for (i=0;i<n;i++){ putchar ( '|' ); for (j=0;j<m;j++) putchar (f[j]); puts ( "|" ); } putchar ( '+' ); for (i=0;i<m;i++) putchar ( '-' ); puts ( "+" ); } } |
F. 延时操控
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | #include<cstdio> const int N=55,K=5,P=1000000007; const int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1}; int Case,n,m,delay,hp,px,py,ex,ey,i,j,k,x,y,d,lim,o; int f[2][N][N][K][K*2][K*2],g[2][N][N],ans; bool ban[N][N]; char ch[N]; inline void up( int &a, int b){a=a+b<P?a+b:a+b-P;} inline bool check( int x, int y){ if (x<1||x>n||y<1||y>n) return 0; return !ban[x][y]; } int main(){ scanf ( "%d" ,&Case); while (Case--){ scanf ( "%d%d%d%d" ,&n,&m,&delay,&hp); for (i=1;i<=n;i++){ scanf ( "%s" ,ch+1); for (j=1;j<=n;j++){ if (ch[j]== '#' )ban[i][j]=1; else ban[i][j]=0; if (ch[j]== 'P' )px=i,py=j; if (ch[j]== 'E' )ex=i,ey=j; } } ex-=px,ey-=py; for (o=0;o<2;o++) for (i=1;i<=n;i++) for (j=1;j<=n;j++) for (k=0;k<hp;k++) for (x=-k;x<=k;x++){ lim=k-(x>0?x:-x); for (y=-lim;y<=lim;y++)f[o][i][j][k][x+K][y+K]=0; } for (o=0;o<2;o++) for (i=1;i<=n;i++) for (j=1;j<=n;j++)g[o][i][j]=0; m-=delay; f[0][px][py][0][K][K]=1; o=0; while (m--){ for (i=1;i<=n;i++) for (j=1;j<=n;j++) for (k=0;k<hp;k++) for (x=-k;x<=k;x++){ lim=k-(x>0?x:-x); for (y=-lim;y<=lim;y++)f[o^1][i][j][k][x+K][y+K]=0; } for (i=1;i<=n;i++) for (j=1;j<=n;j++) for (k=0;k<hp;k++) for (x=-k;x<=k;x++){ lim=k-(x>0?x:-x); for (y=-lim;y<=lim;y++){ int now=f[o][i][j][k][x+K][y+K]; if (!now) continue ; for (d=0;d<4;d++){ px=i+dx[d],py=j+dy[d]; if (!check(px,py)) continue ; if (check(px+ex+x,py+ey+y))up(f[o^1][px][py][k][x+K][y+K],now); else if (k+1==hp)up(g[0][px][py],now); else up(f[o^1][px][py][k+1][x-dx[d]+K][y-dy[d]+K],now); } } } o^=1; } o=0; while (delay--){ for (i=1;i<=n;i++) for (j=1;j<=n;j++)g[o^1][i][j]=0; for (i=1;i<=n;i++) for (j=1;j<=n;j++){ int now=g[o][i][j]; if (!now) continue ; for (d=0;d<4;d++){ px=i+dx[d],py=j+dy[d]; if (!check(px,py)) continue ; up(g[o^1][px][py],now); } } o^=1; } ans=0; for (i=1;i<=n;i++) for (j=1;j<=n;j++)up(ans,g[o][i][j]); printf ( "%d\n" ,ans); } } |
G. 序列更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #include<iostream> #include<algorithm> #include<cmath> using namespace std; const int N=250005; int Case,n,q,lim,i,k,x,a[N],b[N],c[N],cs,ct,S[N],T[N]; long long sum; inline void fix( int &x){ while (x<0)x+=n; while (x>=n)x-=n; } inline void gao( int x, int y){ fix(x); fix(y); if (a[x]>=b[y]) return ; sum+=b[y]-a[x]; a[x]=b[y]; } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while (Case--){ cin>>n>>q; sum=0; for (i=0;i<n;i++){ cin>>a[i]; sum+=a[i]; } for (i=0;i<n;i++)cin>>b[i]; for (i=0;i<n;i++)c[i]=b[i]; sort(c,c+n); lim= sqrt (n); lim=max(lim,1); lim=min(lim,n); lim=c[n-lim]; cs=ct=0; for (i=0;i<n;i++){ if (a[i]<=lim)S[cs++]=i; if (b[i]>lim)T[ct++]=i; } while (q--){ cin>>k; for (i=0;i<cs;){ x=S[i]; gao(x,x+k); if (a[x]>lim)swap(S[i],S[--cs]); else i++; } for (i=0;i<ct;i++){ x=T[i]; gao(x-k,x); } cout<<sum<< "\n" ; } } } |
H. 魔法卡牌
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | #include<cstdio> #include<algorithm> using namespace std; typedef unsigned long long ull; const int N=63,inf=~0U>>1; int Case,n,m,i,j,x,y,a[N],b[N],T[N],a_deg[N],b_deg[N]; ull a_all[N],a_ban[N],a_must[N],b_ban[N],nei[N],imp; bool a_imp[N],can[N][N][2][2]; struct P{ int val;ull way; P(){} P( int _val,ull _way){val=_val;way=_way;} void clr(){val=-inf;way=0;} void up( const P&b, int k=0){ if (val>b.val+k) return ; if (val<b.val+k){ val=b.val+k; way=b.way; return ; } way+=b.way; } void print(){ printf ( "%d %llu\n" ,val,way);} }; P dfs(ull S){ if (!S) return P(0,1); int who=-1,best=inf; int cnt=__builtin_popcountll(S); if (imp&S)who=__builtin_ctzll(imp&S); else for (ull Q=S;Q;Q-=Q&-Q){ int x=__builtin_ctzll(Q); if (__builtin_popcountll(nei[x]&S)<=2) continue ; int a_deg=__builtin_popcountll(a_all[x]&S); int b_deg=__builtin_popcountll(b_ban[x]&S); int now=T[cnt-a_deg-1]+T[cnt-b_deg-1]; if (now<best)who=x,best=now; } if (who<0){ P ans(0,1); for (ull Q=S;Q;){ int head=__builtin_ctzll(Q); Q-=Q&-Q; ull mask=S&nei[head]; if (!mask){ S^=1ULL<<head; ans.val+=max(a[head],b[head]); if (a[head]==b[head])ans.way*=2; continue ; } if ((mask&-mask)!=mask) continue ; S^=1ULL<<head; static P dp[2][2]; int x=head,o=0; for ( int i=0;i<2;i++)dp[0][i].clr(); dp[0][0]=P(a[x],1); dp[0][1]=P(b[x],1); while (S&nei[x]){ int y=__builtin_ctzll(S&nei[x]); S^=1ULL<<y; for ( int j=0;j<2;j++)dp[o^1][j].clr(); for ( int j=0;j<2;j++) if (dp[o][j].way){ if (can[x][y][j][0])dp[o^1][0].up(dp[o][j],a[y]); if (can[x][y][j][1])dp[o^1][1].up(dp[o][j],b[y]); } o^=1; x=y; } P cur(-inf,0); for ( int j=0;j<2;j++) if (dp[o][j].way)cur.up(dp[o][j]); if (!cur.way) return P(-inf,0); ans.val+=cur.val; ans.way*=cur.way; Q&=S; } while (S){ int head=__builtin_ctzll(S); S^=1ULL<<head; static P dp[2][2][2]; int x=head,o=0; for ( int i=0;i<2;i++) for ( int j=0;j<2;j++)dp[0][i][j].clr(); dp[0][0][0]=P(a[x],1); dp[0][1][1]=P(b[x],1); while (S&nei[x]){ int y=__builtin_ctzll(S&nei[x]); S^=1ULL<<y; for ( int i=0;i<2;i++){ for ( int j=0;j<2;j++)dp[o^1][i][j].clr(); for ( int j=0;j<2;j++) if (dp[o][i][j].way){ if (can[x][y][j][0])dp[o^1][i][0].up(dp[o][i][j],a[y]); if (can[x][y][j][1])dp[o^1][i][1].up(dp[o][i][j],b[y]); } } o^=1; x=y; } P cur(-inf,0); for ( int i=0;i<2;i++) for ( int j=0;j<2;j++) if (dp[o][i][j].way&&can[head][x][i][j])cur.up(dp[o][i][j]); if (!cur.way) return P(-inf,0); ans.val+=cur.val; ans.way*=cur.way; } return ans; } S^=1ULL<<who; P ans(-inf,0); for ( int o=0;o<2;o++){ ull nS=S,SA=0,SB=0,Q=0; int val=0; if (!o){ if (a_imp[who]) continue ; val=a[who]; SA^=a_must[who]&nS; SB^=a_ban[who]&nS; Q=a_all[who]&S; } else { val=b[who]; SB^=b_ban[who]&nS; Q=b_ban[who]&nS; } nS^=Q; while (Q){ int x=__builtin_ctzll(Q); if (SA>>x&1){ val+=a[x]; if (a_ban[x]&SA) break ; if (a_must[x]&SB) break ; if (a_imp[x]) break ; SA^=a_must[x]&nS; SB^=a_ban[x]&nS; Q^=a_all[x]&nS; nS^=a_all[x]&nS; } else { val+=b[x]; if (b_ban[x]&SA) break ; SB^=b_ban[x]&nS; Q^=b_ban[x]&nS; nS^=b_ban[x]&nS; } Q^=1ULL<<x; } if (Q) continue ; P res=dfs(nS); ans.up(res,val); } return ans; } int main(){ for (i=0;i<N;i++){ if (i<=3)T[i]=1; else T[i]=max(T[i-1]+T[max(i-5,0)],max(T[i-2]+T[i-4],T[i-3]+T[i-3])); //printf("T[%d]=%d\n",i,T[i]); } scanf ( "%d" ,&Case); while (Case--){ scanf ( "%d%d" ,&n,&m); for (i=0;i<n;i++){ scanf ( "%d%d" ,&a[i],&b[i]); a_ban[i]=a_must[i]=b_ban[i]=0; } for (i=0;i<n;i++) for (j=0;j<n;j++) for (x=0;x<2;x++) for (y=0;y<2;y++)can[i][j][x][y]=1; while (m--){ char op[9]; scanf ( "%s%d%d" ,op,&x,&y); x--;y--; if (op[0]== 'A' ){ //x -> !y //y -> !x a_ban[x]|=1ULL<<y; a_ban[y]|=1ULL<<x; can[x][y][0][0]=0; can[y][x][0][0]=0; } else { //x -> y //!y -> !x a_must[x]|=1ULL<<y; b_ban[y]|=1ULL<<x; can[x][y][0][1]=0; can[y][x][1][0]=0; } } imp=0; for (i=0;i<n;i++){ a_imp[i]=!!(a_ban[i]&a_must[i]); if (a_imp[i])imp|=1ULL<<i; a_all[i]=a_ban[i]|a_must[i]; nei[i]=a_all[i]|b_ban[i]; } P ans=dfs((1ULL<<n)-1); ans.print(); } } |
I. 昵称检索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #include<iostream> #include<string> using namespace std; const int N=1000005,day[13]={0,31,29,31,30,31,30,31,31,30,31,30,31}; int Case,n,m,i,j,x,ans,suf[N],f[N][26],vis[26];string a; inline int godate( int *s){ int x=m+1; for ( int i=3;~i;i--){ x--; if (x<1) return 0; x=f[x][s[i]]; } return x; } inline int goname(){ int x=0; for ( int i=0;i<a.size();i++){ x++; if (x>m) return m+1; x=f[x][a[i]- 'a' ]; } return x; } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while (Case--){ cin>>n>>m>>a; for (j=0;j<10;j++)vis[j]=0; for (i=1;i<=m;i++){ if (a[i-1]>= '0' &&a[i-1]<= '9' )vis[a[i-1]- '0' ]=i; for (j=0;j<10;j++)f[i][j]=vis[j]; } for (i=0;i<=m+1;i++)suf[i]=0; for (i=1;i<=12;i++) for (j=1;j<=day[i];j++){ static int pool[4]; pool[0]=i/10; pool[1]=i%10; pool[2]=j/10; pool[3]=j%10; x=godate(pool); if (x)suf[x]++; } for (i=m;i>1;i--)suf[i-1]+=suf[i]; for (j=0;j<26;j++)vis[j]=m+1; for (i=m;i;i--){ if (a[i-1]>= 'a' &&a[i-1]<= 'z' )vis[a[i-1]- 'a' ]=i; for (j=0;j<26;j++)f[i][j]=vis[j]; } ans=0; while (n--){ cin>>a; x=goname(); if (x<m)ans+=suf[x+1]; } cout<<ans<< "\n" ; } } |
J. 矩阵的周期
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | #include<cstdio> typedef unsigned long long ull; const int N=63,M=1200005; int Case,n,m,o,i,j,k,at[N],w[N],lim[N],nxt[M]; bool g[N][N],h[N][N],can[N][N]; ull adj[N],sub0[(1<<20)+1],sub1[(1<<20)+1],sub2[(1<<20)+1],f[M]; int gcd( int a, int b){ return b?gcd(b,a%b):a;} inline int lcm( int a, int b){ return a/gcd(a,b)*b;} inline int getlim( int o, int x){ if (!can[o][x]) return 1; if (w[o]>1||w[x]>1||at[o]==at[x]) return n; int ret=1; for ( int i=0;i<n;i++) if (can[o][i]&&can[i][x])ret=lcm(ret,w[i]); return ret; } inline int getper( int x){ int m=lim[x],i,j; for (nxt[1]=j=0,i=2;i<=m;nxt[i++]=j){ while (j&&((f[j+1]^f[i])>>x&1))j=nxt[j]; if (!((f[j+1]^f[i])>>x&1))j++; } return m-nxt[m]; } int main(){ scanf ( "%d" ,&Case); while (Case--){ scanf ( "%d" ,&n); for (i=0;i<n;i++){ char ch[N]; scanf ( "%s" ,ch); adj[i]=0; for (j=0;j<n;j++){ g[i][j]=ch[j]== '1' ; if (g[i][j])adj[i]|=1ULL<<j; } } for (i=0;i<n;i++) for (j=0;j<n;j++)can[i][j]=g[i][j]|(i==j); for (k=0;k<n;k++) for (i=0;i<n;i++) for (j=0;j<n;j++)can[i][j]|=can[i][k]&can[k][j]; for (i=0;i<n;i++)w[i]=0; for (i=0;i<n;i++){ if (w[i]) continue ; m=0; for (j=i;j<n;j++) if (can[i][j]&&can[j][i])m++; for (j=i;j<n;j++) if (can[i][j]&&can[j][i]){ at[j]=i; w[j]=m; } } for (o=0;o<N;o++){ for (i=0;i<n;i++) for (j=0;j<n;j++)h[i][j]=0; for (i=0;i<n;i++) for (j=0;j<n;j++) for (k=0;k<n;k++)h[i][k]|=g[i][j]&g[j][k]; for (i=0;i<n;i++) for (j=0;j<n;j++)g[i][j]=h[i][j]; } m=1<<(n<20?n:20); for (i=0;i<m;i++)sub0[i]=sub1[i]=sub2[i]=0; for (i=0;i<n;i++){ j=i; if (j<20){sub0[1<<j]|=adj[i]; continue ;} else j-=20; if (j<20){sub1[1<<j]|=adj[i]; continue ;} else j-=20; sub2[1<<j]|=adj[i]; } for (i=2;i<m;i++){ j=i&-i; sub0[i]=sub0[i^j]|sub0[j]; sub1[i]=sub1[i^j]|sub1[j]; sub2[i]=sub2[i^j]|sub2[j]; } for (o=0;o<n;o++){ m=1; for (i=0;i<n;i++){ lim[i]=getlim(o,i)*2; if (m<lim[i])m=lim[i]; } ull S=0; for (i=0;i<n;i++) if (g[o][i])S|=1ULL<<i; for (i=1;i<=m;i++){ f[i]=S; S=sub0[S&1048575]|sub1[S>>20&1048575]|sub2[S>>40]; } for (i=0;i<n;i++) printf ( "%d%c" ,getper(i),i+1<n? ' ' : '\n' ); } } } |
K. 找环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | #include<iostream> using namespace std; typedef unsigned int U; typedef unsigned long long ull; const int N=1005,M=2005,TOT=N*M*11,BASE=998244353,P=1000000007; ull weight[N]; U SX=335634763,SY=873658265,SZ=192849106,SW=746126501; inline ull xorshift128(){ U t=SX^(SX<<11); SX=SY; SY=SZ; SZ=SW; return SW=SW^(SW>>19)^t^(t>>8); } inline ull myrand(){ return (xorshift128()<<32)^xorshift128();} int Case,inv[N],n,m,i,j,res,f[N][N],tot,l[TOT],r[TOT],val[TOT];ull sum[TOT]; struct E{ int x,y,z;}e[M]; struct Frac{ int u1,u2,d; Frac(){} Frac( int _u1, int _u2, int _d){u1=_u1,u2=_u2,d=_d;} }; int ins( int x, int a, int b, int c){ int y=++tot; val[y]=val[x]+1; sum[y]=sum[x]+weight[c]; if (a==b) return y; int mid=(a+b)>>1; if (c<=mid)l[y]=ins(l[x],a,mid,c),r[y]=r[x]; else l[y]=l[x],r[y]=ins(r[x],mid+1,b,c); return y; } inline bool smaller( int x, int y){ if (y<0) return 1; if (sum[x]==sum[y]) return 0; int a=1,b=n,mid; while (a<b){ mid=(a+b)>>1; if (sum[r[x]]==sum[r[y]]){ b=mid; x=l[x]; y=l[y]; } else { a=mid+1; x=r[x]; y=r[y]; } } return val[x]<val[y]; } inline int compare( const Frac&A, const Frac&B){ if (A.u1<0&&B.u1<0) return 0; if (A.u1<0) return 1; if (B.u1<0) return -1; int a=1,b=n,mid; int A1=A.u1,A2=A.u2,B1=B.u1,B2=B.u2,AD=A.d,BD=B.d; if ((sum[A1]-sum[A2])*BD==(sum[B1]-sum[B2])*AD) return 0; //(A1-A2)/AD<(B1-B2)/BD //(A1-A2)*BD<(B1-B2)*AD while (a<b){ mid=(a+b)>>1; if ((sum[r[A1]]-sum[r[A2]])*BD==(sum[r[B1]]-sum[r[B2]])*AD){ b=mid; A1=l[A1]; A2=l[A2]; B1=l[B1]; B2=l[B2]; } else { a=mid+1; A1=r[A1]; A2=r[A2]; B1=r[B1]; B2=r[B2]; } } int cross=(val[A1]-val[A2])*BD-(val[B1]-val[B2])*AD; if (!cross) return 0; return cross<0?-1:1; } void cal( int x, int y, int a, int b){ if (a==b){ res=(1LL*res*BASE+val[x]-val[y])%P; return ; } int mid=(a+b)>>1; cal(r[x],r[y],mid+1,b); cal(l[x],l[y],a,mid); } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; for (inv[0]=inv[1]=1,i=2;i<N;i++)inv[i]=1LL*(P-P/i)*inv[P%i]%P; while (Case--){ cin>>n>>m; for (i=1;i<=m;i++)cin>>e[i].x>>e[i].y>>e[i].z; for (i=1;i<=n;i++)weight[i]=myrand(); for (i=0;i<=n+1;i++) for (j=1;j<=n;j++)f[i][j]=-1; for (j=1;j<=n;j++)f[0][j]=0; for (i=0;i<=n;i++) for (j=1;j<=m;j++){ int x=e[j].x,y=e[j].y,z=e[j].z; int root=f[i][x]; if (root<0) continue ; int now=ins(root,1,n,z+1); if (smaller(now,f[i+1][y]))f[i+1][y]=now; } Frac ans=Frac(-1,-1,1); for (i=1;i<=n;i++){ int fin=f[n+1][i]; if (fin<0) continue ; Frac me=Frac(0,0,1); for (j=0;j<=n;j++){ int now=f[j][i]; if (now<0) continue ; Frac tmp(fin,now,n+1-j); if (compare(tmp,me)>0)me=tmp; } if (compare(me,ans)<0)ans=me; } if (ans.u1<0)cout<< "-1\n" ; else { res=0; cal(ans.u1,ans.u2,1,n); res=1LL*res*inv[ans.d]%P; cout<<res<< "\n" ; } for (i=1;i<=tot;i++)l[i]=r[i]=val[i]=sum[i]=0; tot=0; } } |
L. 寻找宝藏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #include<iostream> #include<algorithm> #include<vector> using namespace std; typedef long long ll; const int N=300005; int Case,n,m,i;ll bit[N];vector< int >gl[N],gr[N]; struct E{ int y,w;ll pre,suf,val;}e[N]; struct Qry{ int yl,yr;ll ans,ur,ru;}q[N]; inline void up(ll&a,ll b){a<b?(a=b):0;} inline void ins( int x,ll p){ for (;x<=n;x+=x&-x)up(bit[x],p);} inline ll ask( int x){ ll t=0; for ((x>n)&&(x=n);x;x-=x&-x)up(t,bit[x]); return t; } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while (Case--){ cin>>n>>m; for (i=1;i<=n;i++){ cin>>e[i].y>>e[i].w; gl[i].clear(); gr[i].clear(); } for (i=1;i<=m;i++){ int xl,xr; cin>>xl>>q[i].yl>>xr>>q[i].yr; gl[xl].emplace_back(i); gr[xr].emplace_back(i); } for (i=1;i<=n;i++)bit[i]=0; for (i=1;i<=n;i++){ for ( const auto &j:gl[i])q[j].ur=ask(q[j].yr); e[i].pre=ask(e[i].y)+e[i].w; ins(e[i].y,e[i].pre); for ( const auto &j:gr[i])q[j].ru=ask(q[j].yl-1); } for (i=0;i<=n;i++)bit[i]=0; for (i=n;i;i--){ for ( const auto &j:gr[i])q[j].ru+=ask(n+1-q[j].yl); e[i].suf=ask(n+1-e[i].y)+e[i].w; ins(n+1-e[i].y,e[i].suf); e[i].val=e[i].pre+e[i].suf-e[i].w; for ( const auto &j:gl[i])q[j].ur+=ask(n+1-(q[j].yr+1)); } for (i=1;i<=m;i++)q[i].ans=max(q[i].ur,q[i].ru); for (i=1;i<=n;i++)bit[i]=0; for (i=1;i<=n;i++){ for ( const auto &j:gl[i])up(q[j].ans,ask(n+1-(q[j].yr+1))); ins(n+1-e[i].y,e[i].val); } for (i=1;i<=n;i++)bit[i]=0; for (i=n;i;i--){ for ( const auto &j:gr[i])up(q[j].ans,ask(q[j].yl-1)); ins(e[i].y,e[i].val); } for (i=1;i<=m;i++)cout<<q[i].ans<< "\n" ; } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决
2015-08-04 BZOJ3095 : 二元组
2015-08-04 BZOJ4042 : [Cerc2014] parades
2015-08-04 BZOJ4049 : [Cerc2014] Mountainous landscape