noip simulation tests 19


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;
}
t1 Code

 


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 }
t2 Code

 


 

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 }
t3 Code

 

Guess you like

Origin www.cnblogs.com/Gkeng/p/11354365.html