10.27night清北刷题班
/* 枚举每个部分的总和,利用前缀和进行检验。 如果能分成4部分就一定能分成2部分,就筛了一边素数优化。
清空数组!!! */ #include<bits/stdc++.h> #define N 1000001 using namespace std; int prime[N],no[N]={0,1},num[N],sum[N]; int n,m,tot,cur,tmp,flag; char s[N]; bool vis[N]; void pri() { for(int i=2;i<=N;i++) { if(!no[i]) prime[++tot]=i; for(int j=1;j<=tot;j++) { if(i*prime[j]>=N)break; no[i*prime[j]]=1; if(i%prime[j]==0) break; } } } int main() { freopen("divie.in","r",stdin); freopen("divide.out","w",stdout); int T;scanf("%d",&T); pri(); while(T--) { scanf("%s",s+1); n=strlen(s+1);int opt=0; memset(num,0,sizeof num); memset(sum,0,sizeof sum); memset(vis,0,sizeof vis); for(int i=1;i<=n;i++) num[i]=s[i]-'0'; for(int i=1;i<=n;i++) sum[i]=sum[i-1]+num[i],vis[sum[i]]=1; if(sum[n]==0) {printf("YES\n");continue;} for(int i=1;i<=min(n,tot);i++) { if(prime[i]>sum[n]) break; if(sum[n]%prime[i]) continue; cur=prime[i];tmp=sum[n]/prime[i]; flag=0; for(int j=1;j<=cur;j++) if(!vis[j*tmp]){flag=1;break;} if(!flag) {opt=1;printf("YES\n");break;} } if(opt) continue; printf("NO\n"); } return 0; }
\
/* dp[n]表示n个点,每个点都和点1相连,且n个点互相连通的图的个数。 S[n]总的个数 g[n]表示n个点,每个点都和点1相连,且不是n个点互相连通的图的个数。 考虑从除了1之外的n-1个点中选出i-1个点,让这i个点互相连通,而剩下的n-i个点和这i个点没有边相连,互相之间随意连接。 这个代码5000要跑1.6s,所以后面90%数据打表23333 100%需要fft优化。 */ #include<bits/stdc++.h> #define N 50001 #define ll long long #define M 998244353 using namespace std; ll fac[N]={1,1},inv[N]={1,1},f[N]={1,1}; ll dp[N],g[N],S[N]; int n; ll C(ll a,ll b) { return fac[a]*inv[b]%M*inv[a-b]%M; } ll kfc(ll x,ll y) { x=x%M,y=y%M; return ((x*y-(ll)(((long double)x*y+0.5)/M)*M)%M+M)%M; } ll ksm(ll a,ll b) { ll res=1; while(b) { if(b&1) res=kfc(res,a)%M; b>>=1; a=kfc(a,a)%M; }return res%M; } void init() { for(int i=2;i<N;i++) { fac[i]=fac[i-1]*i%M; f[i]=(M-M/i)*f[M%i]%M; inv[i]=inv[i-1]*f[i]%M; } } int main() { freopen("count.in","r",stdin); freopen("count.out","w",stdout); cin>>n;init(); dp[1]=1;g[1]=0; for(int i=1;i<=5000;i++) S[i]=ksm(2,(i*(i-1))/2); for(int i=2;i<=5000;i++) { g[i]=0; for(int j=1;j<i;j++) g[i] =(g[i]+(C(i-1,j-1)*dp[j]%M*S[i-j])%M)%M; dp[i]=(S[i]-g[i]+M)%M; } cout<<dp[n]<<endl; return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 暴力枚举选哪几条路径 */ #include<bits/stdc++.h> #define N 100007 #define ll long long using namespace std; ll n,m,ans,cnt,flag,cur; ll head[N],deep[N],sum[N],f[N][28]; ll vis[N],choose[N],W[N]; struct edge{ ll u,v,net; }e[N<<1]; struct node{ int pos,x,y; }p[N]; inline ll read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } inline ll max(ll a,ll b){return a>b?a:b;} inline void add(int u,int v) { e[++cnt].v=v;e[cnt].net=head[u];head[u]=cnt; } void DFS(int u,int fa,int c) { f[u][0]=fa;deep[u]=c; for(int i=head[u];i;i=e[i].net) { int v=e[i].v; if(v==fa) continue; sum[v]+=sum[u]; DFS(v,u,c+1); } } void get() { for(int j=1;j<=27;j++) for(int i=1;i<=n;i++) f[i][j]=f[f[i][j-1]][j-1]; } int lca(int a,int b) { if(deep[a]<deep[b]) swap(a,b); int t=deep[a]-deep[b]; for(int i=0;i<=26;i++) if(t&(1<<i)) a=f[a][i]; if(a==b) return a; for(int i=26;i>=0;i--) if(f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i]; return f[a][0]; } ll S(ll a,ll b) { int res=lca(a,b); return sum[a]+sum[b]-2*sum[res]+W[res]; } void expand(int i) { int x=p[i].x,y=p[i].y,res=lca(x,y); if(vis[res]) {flag=1;return;} while(x!=res) { if(vis[x]) {flag=1;break;} vis[x]=1;x=f[x][0]; } while(y!=res){if(vis[y]){vis[y]=2;flag=1;}else vis[y]=1;y=f[y][0];}vis[res]=1; } void clear(int i) { int x=p[i].x,y=p[i].y,res=lca(x,y); if(x==res && vis[x]) vis[x]--; if(y==res && vis[y]) vis[y]--; while(x!=res){vis[x]=0;x=f[x][0];} while(y!=res){if(vis[y])vis[y]--;y=f[y][0];}if(x!=res && y!=res)vis[res]--; } void dfs(int k,int tot,int lim) { if(tot==lim) { flag=0,cur=0; memset(vis,0,sizeof vis); for(int i=1;i<=m;i++) { if(choose[i]) { expand(i); if(flag) return; else cur+=S(p[i].x,p[i].y); } } ans=max(ans,cur); return; } for(int i=k;i<=m;i++) { if(choose[i]) continue; choose[i]=1;dfs(i+1,tot+1,lim); choose[i]=0; clear(i); } } int main() { freopen("ly.in","r",stdin); int x,y; n=read(); for(int i=1;i<=n;i++) W[i]=sum[i]=read(); for(int i=1;i<n;i++) { x=read();y=read(); add(x,y);add(y,x); } DFS(1,1,0);get(); m=read(); for(int i=1;i<=m;i++) { p[i].x=read();p[i].y=read();p[i].pos=i; ans=max(ans,S(p[i].x,p[i].y)); } for(int i=1;i<=n/2;i++) { memset(choose,0,sizeof choose); memset(vis,0,sizeof vis); dfs(1,0,i); } printf("%lld\n",ans); return 0; } /* 10 1 2 3 4 5 6 7 8 9 10 10 6 9 6 3 1 6 7 6 3 3 8 8 5 8 4 2 6 4 2 3 3 4 4 5 9 1 */
折花枝,恨花枝,准拟花开人共卮,开时人去时。
怕相思,已相思,轮到相思没处辞,眉间露一丝。