T1:Count
First easy to find the block size must be a divisor of n, the number of enumerated about $ O (\ sqrt n) $
Consider how judgment
Set block size k
Found subtree $ (a) as long as the lowermost $ size $ k $, comprising a subtree $ (b) $ size $ 2k $, comprising b subtrees $ (C) $ size $. 3K $ ... ...
Namely: only have $ n / k $ subtrees of size to multiples of $ k $
So you can $ O (n) $ is determined, and then no brain submit $ O (n \ sqrt n) $ millions? ? ?
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> #include<queue> #include<cstdlib> #include<vector> using namespace std; const int MAXN=1000005; int n,ans,siz[MAXN]; struct node { int to,nxt; }mp[MAXN*2]; int h[MAXN],tot; void dfs(int u,int fa) { siz[u]=1; for(int i=h[u];i;i=mp[i].nxt) { int v=mp[i].to; if(v==fa) continue; dfs(v,u); siz[u]+=siz[v]; } } inline int R() { int a=0;char c=getchar(); while(c>'9'||c<'0')c=getchar(); while(c>='0'&&c<='9')a=a*10+c-'0',c=getchar(); return a; } int main() { n=R(); for(int i=1,aa,bb;i<n;++i) { aa=R();bb=R(); mp[++tot].nxt=h[aa]; mp[tot].to=bb;h[aa]=tot; mp[++tot].nxt=h[bb]; mp[tot].to=aa;h[bb]=tot; } dfs(1,0); for(int i=2;i<n;++i) if(n%i==0) { int cnt=0; for(int j=1;j<=n;j++) if(siz[j]%i==0) ++cnt; if(n/i==cnt) ++ans; } printf("%d\n",ans+2); return 0; }
T2:Dinner
Unexpectedly doubled, the two points can be thought of jump, but did not give a range of m, n and m if the same level of complexity to burst, so did not write
It was found that m actually very small, a lot of people are using two watershed over ......
First-off ring into a chain, the answer bipartite
Determination is the most violent enumerate the endpoint, and then step by step greedy jump, the complexity of the $ (n ^ 2logn) O $
Consider the complexity of optimizing jump
For each check, can $ O (nlogn) $ pretreatment jump $ 2 ^ n $ steps may skip where
M binary jump is then disassembled, the complexity of $ O ((nlogn + logm) * logn) $, m and n are the same level if the $ O (nlog ^ 2n) $
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 #include<iostream> 6 #include<queue> 7 #include<cstdlib> 8 #include<vector> 9 using namespace std; 10 const int MAXN=50005; 11 int n,m,ans,suma,mx,t[MAXN*2],nxt[MAXN*2][20]; 12 inline int R() { 13 int a=0;char c=getchar(); 14 while(c>'9'||c<'0')c=getchar(); 15 while(c>='0'&&c<='9')a=a*10+c-'0',c=getchar(); 16 return a; 17 } 18 bool check(int lim) { 19 for(int i=1;i<=n;i++) { 20 int pos=i,tm=m; 21 for(int j=18;j>=0;j--) { 22 if((1<<j)>tm) continue; 23 pos=nxt[pos][j]; 24 tm-=(1<<j); 25 } 26 if(pos-i>=n) return 1; 27 } 28 return 0; 29 } 30 void first(int lim) { 31 int l=1,sum=0; 32 for(int i=1;i<=2*n;i++) 33 if(sum+t[i]<=lim) sum+=t[i]; 34 else { 35 while(l<i&&sum+t[i]>lim) { 36 nxt[l][0]=i; 37 sum-=t[l]; 38 ++l; 39 } 40 sum+=t[i]; 41 } 42 while(l<=2*n) nxt[l][0]=2*n+1,++l; 43 for(int i=0;i<=18;i++) nxt[2*n+1][i]=2*n+1; 44 for(int i=1;i<=18;i++) 45 for(int j=1;j+(1<<(i-1))<=2*n;j++) 46 nxt[j][i]=nxt[nxt[j][i-1]][i-1]; 47 } 48 int main() { 49 scanf("%d%d",&n,&m); 50 for(int i=1;i<=n;++i) scanf("%d",&t[i]); 51 for(int i=1;i<=n;++i) 52 t[i+n]=t[i],suma+=t[i],mx=max(mx,t[i]); 53 int l=mx,r=suma; 54 while(l<=r) { 55 int mid=(l+r)>>1; 56 first(mid); 57 if(check(mid)) 58 ans=mid,r=mid-1; 59 else l=mid+1; 60 } 61 printf("%d\n",ans); 62 return 0; 63 }
T3: Chess
First, the first question is simple, can be directly built in the deque or bfs FIG shortest run
Then look at the second question, find different considered different only take the open space plan
Range finding n is small, so dfs for each block enemy communication, to see if it is connected to the space which, in the open space between these side connected twenty-two
Then the open space between the two can be connected directly to the edge
In particular: the enemy can be seen as a handsome open space even side
Shortest count ran on the line
Note: the same side of even only once, it is possible to keep the edge adjacency matrix
(A little cancer ......)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<iostream> 7 #include<queue> 8 #include<vector> 9 #define ll long long 10 using namespace std; 11 const int MAXN=70,INF=0x3f3f3f3f; 12 int n,m,bx,by,ex,ey,eid,s[MAXN][MAXN]; 13 int dx[8]={-1,-2,-2,-1,1,2,2,1},dy[8]={-2,-1,1,2,2,1,-1,-2}; 14 struct node { 15 int to,nxt,dis; 16 }mp[MAXN*MAXN*8]; 17 int h[MAXN*MAXN],tot; 18 int id(int x,int y) { 19 return (x-1)*m+y; 20 } 21 void add(int x,int y,int z) { 22 mp[++tot].dis=z; 23 mp[tot].to=y; 24 mp[tot].nxt=h[x]; 25 h[x]=tot; 26 } 27 void build() { 28 for(int i=1;i<=n;i++) { 29 for(int j=1;j<=m;j++) { 30 if(s[i][j]==2) continue; 31 if(s[i][j]==4) {ex=i,ey=j;continue;} 32 if(s[i][j]==3) bx=i,by=j; 33 for(int k=0;k<8;k++) { 34 int nx=i+dx[k],ny=j+dy[k]; 35 if(nx<1||ny<1||nx>n||ny>m) continue; 36 if(s[nx][ny]==2) continue; 37 add(id(i,j),id(nx,ny),s[nx][ny]!=1&&s[nx][ny]!=4); 38 } 39 } 40 } 41 } 42 int ver[MAXN*MAXN][MAXN*MAXN],dis[MAXN*MAXN]; 43 vector<int> tver; 44 bool vis[MAXN*MAXN],flag; 45 void dfs(int u) { 46 for(int i=h[u];i;i=mp[i].nxt) { 47 int v=mp[i].to; 48 if(vis[v]) continue; 49 vis[v]=1; 50 if(v==eid) flag=1; 51 if(!mp[i].dis) dfs(v); 52 else if(mp[i].dis==1) tver.push_back(v); 53 } 54 } 55 void new_build() { 56 eid=id(ex,ey); 57 memset(vis,0,sizeof(vis)); 58 for(int i=1;i<=n;i++) { 59 for(int j=1;j<=m;j++) if(s[i][j]==1){ 60 tver.clear();flag=0; 61 vis[id(i,j)]=1;dfs(id(i,j)); 62 for(int k=0;k<tver.size();++k) 63 for(int l=0;l<tver.size();++l) 64 ver[tver[k]][tver[l]]=ver[tver[l]][tver[k]]=1; 65 if(flag) for(int k=0;k<tver.size();++k) 66 ver[tver[k]][eid]=1; 67 memset(vis,0,sizeof(vis)); 68 } 69 } 70 for(int i=1;i<=n;i++) 71 for(int j=1;j<=m;j++) if(s[i][j]==0||s[i][j]==3) 72 for(int k=h[id(i,j)];k;k=mp[k].nxt) 73 if(mp[k].dis||mp[k].to==eid) 74 ver[id(i,j)][mp[k].to]=ver[mp[k].to][id(i,j)]=1; 75 } 76 ll cnt[MAXN*MAXN]; 77 void get_cnt() { 78 memset(dis,0x3f,sizeof(dis)); 79 dis[id(bx,by)]=0;cnt[id(bx,by)]=1; 80 priority_queue<pair<int,int> > q; 81 q.push(make_pair(0,id(bx,by))); 82 while(!q.empty()) { 83 int u=q.top().second; q.pop(); 84 if(vis[u]) continue; 85 vis[u]=1; 86 for(int i=1;i<=n*m;i++) if(i!=u){ 87 int v=i,ds=ver[u][i]; 88 if(!ds) continue; 89 if(dis[v]>dis[u]+ds) { 90 dis[v]=dis[u]+ds; 91 cnt[v]=cnt[u]; 92 q.push(make_pair(-dis[v],v)); 93 } else if(dis[v]==dis[u]+ds) cnt[v]+=cnt[u]; 94 } 95 } 96 printf("%lld\n",cnt[eid]); 97 } 98 void dijkstra() { 99 priority_queue<pair<int,int> > q; 100 q.push(make_pair(0,id(bx,by))); 101 memset(dis,0x3f,sizeof(dis)); 102 dis[id(bx,by)]=0; 103 while(!q.empty()) { 104 int u=q.top().second; q.pop(); 105 if(vis[u]) continue; 106 vis[u]=1; 107 for(int i=h[u];i;i=mp[i].nxt) { 108 int v=mp[i].to,ds=mp[i].dis; 109 if(dis[v]>dis[u]+ds) { 110 dis[v]=dis[u]+ds; 111 q.push(make_pair(-dis[v],v)); 112 } 113 } 114 } 115 if(dis[id(ex,ey)]==INF) { 116 printf("-1\n");exit(0); 117 } else printf("%d\n",dis[id(ex,ey)]); 118 } 119 int main() { 120 scanf("%d%d",&n,&m); 121 for(int i=1;i<=n;i++) 122 for(int j=1;j<=m;j++) 123 scanf("%d",&s[i][j]); 124 build(); 125 dijkstra(); 126 new_build(); 127 get_cnt(); 128 return 0; 129 }