1.

有n 栋居民楼分布在一条竖直的街道上,第i 栋居民楼位于xi 处, 有ai 个住户。
现在所有住户都搭乘同一辆车回家,并且已经全部上车。车初始时位于S 处,并以恒定速度行驶。
车辆的行驶方向由投票决定,一人一票,不能不投,平票就向负方向开。所有住户都想尽早到家,他们会选取最优策略来投票,如果投给正方向和负方向的结果一样,那么他就会投个负方向。
请你输出车辆一共会行驶多少路程。n<=10^5

仍然是考虑特殊情况,比如说最左边和最右边的人。若最左边的票数小于最右边的票数,那么最左边一定会不停地支持右边,直到最右边的人到家了。

维护这个过程即可。

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 template<typename tn> void read(tn &a){
 5     tn x=0,f=1; char c=' ';
 6     for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
 7     for(;isdigit(c);c=getchar()) x=x*10+c-'0';
 8     a=x*f;
 9 }
10 int n,S;
11 ll ans;
12 map<int,ll> mp;
13 void solve(){
14     if(mp.size()<2){
15         ans+=abs(mp.begin()->first-S);
16         S=mp.begin()->first;
17         return;
18     }
19     if(S<=mp.begin()->first||S>=mp.rbegin()->first){
20         ans+=max(abs(mp.begin()->first-S),abs(mp.rbegin()->first-S));
21         S=mp.begin()->first>=S?mp.rbegin()->first:mp.begin()->first;
22         return;
23     }
24     if(mp.rbegin()->second>mp.begin()->second){
25         mp.rbegin()->second+=mp.begin()->second;
26         int w=mp.begin()->first;
27         mp.erase(mp.begin());
28         solve();
29         ans+=abs(w-S);S=w;
30     }
31     else{
32         mp.begin()->second+=mp.rbegin()->second;
33         int w=mp.rbegin()->first;
34         mp.erase(--mp.end());
35         solve();
36         ans+=abs(w-S);S=w;
37     }
38 
39 }
40 int main(){
41     freopen("home.in","r",stdin);
42     freopen("home.out","w",stdout);
43     read(n);read(S);
44     for(int i=1;i<=n;i++){
45         int x,p;read(x);read(p);
46         mp[x]+=p;
47     }
48     solve();
49     cout<<ans<<'\n';
50     return 0;
51 }
View Code

2.套路题。

 


3.CF512D Fox And Travelling

对于有根数,简单去重即可。

背包合并一下即可。

  1 #define mod 1000000009
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 typedef long long int ll;
  5 int n,m;
  6 int vis[2333],deg[2333],sum[2333];
  7 int size,head[305*305];
  8 bool used[2333];
  9 ll f[305][305][2],c[305][305];
 10 struct edge
 11 {
 12     int to,next;
 13 }E[305*305];
 14 inline void addE(int u,int v)
 15 {
 16     E[++size].to=v;
 17     E[size].next=head[u];
 18     head[u]=size;
 19 }
 20 inline void add(ll&x,ll y)
 21 {
 22     x=(x+y)%mod;
 23 }
 24 inline ll qpow(ll x,ll y)
 25 {
 26     ll ans=1,base=x;
 27     while(y)
 28     {
 29         if(y&1)
 30             ans=ans*base%mod;
 31         base=base*base%mod;
 32         y>>=1;
 33     }
 34     return ans;
 35 }
 36 void init()
 37 {
 38     for(int i=0;i<=200;++i)
 39     {
 40         c[i][0]=1;
 41         for(int j=1;j<=i;++j)
 42             c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
 43     }
 44     queue<int>Q;
 45     for(int i=1;i<=n;++i)
 46         if(deg[i]<=1)
 47         {
 48             vis[i]=1;
 49             Q.push(i);
 50         }
 51     while(!Q.empty())
 52     {
 53         int u=Q.front();
 54         Q.pop();
 55         for(int i=head[u];i;i=E[i].next)
 56         {
 57             int v=E[i].to;
 58             if(vis[v])
 59                 continue;
 60             --deg[v];
 61             if(deg[v]==1)
 62             {
 63                 vis[v]=1;
 64                 Q.push(v);
 65             }
 66         }
 67     }
 68 }
 69 inline int findRoot(int S)
 70 {
 71     queue<int>Q;
 72     Q.push(S);
 73     used[S]=1;
 74     int p=-1;
 75     while(!Q.empty())
 76     {
 77         int u=Q.front();
 78         Q.pop();
 79         for(int i=head[u];i;i=E[i].next)
 80         {
 81             int v=E[i].to;
 82             if(!vis[v])
 83                 p=u;
 84             else if(vis[v]&&!used[v])
 85             {
 86                 used[v]=1;
 87                 Q.push(v);
 88             }
 89         }
 90     }
 91     return p;
 92 }
 93 inline ll C(int x,int y)
 94 {
 95     if(x<y||x<0||y<0)
 96         return 0;
 97     return c[x][y];
 98 }
 99 ll ans[305],wait[305],tmp[305][2];
100 void dfs(int u,int F)
101 {
102     sum[u]=1;
103     memset(f[u],0,sizeof(f[u]));
104     f[u][0][0]=1;
105     f[u][1][1]=1;
106     for(int e=head[u];e;e=E[e].next)
107     {
108         int v=E[e].to;
109         if(v==F||!vis[v])//!!!!!!!!!!!!
110             continue;
111         dfs(v,u);
112         for(int i=0;i<=sum[u]+sum[v];++i)
113             tmp[i][0]=tmp[i][1]=0;
114         for(int i=0;i<=sum[u];++i)
115             for(int j=0;j<=sum[v];++j)
116             {
117                 add(tmp[i+j][0],f[u][i][0]*(f[v][j][0]+f[v][j][1])%mod*C(i+j,j));
118                 if(j==sum[v])
119                     add(tmp[i+j][1],f[u][i][1]*f[v][j][1]%mod*C(i+j-1,j));
120             }
121         sum[u]+=sum[v];
122         for(int i=0;i<=sum[u];++i)
123             f[u][i][0]=tmp[i][0],f[u][i][1]=tmp[i][1];
124     }
125 }
126 inline void update()
127 {
128     memset(tmp,0,sizeof(tmp));
129     for(int i=0;i<=n;++i)
130         for(int j=0;j<=n-i;++j)
131             add(tmp[i+j][0],ans[i]*wait[j]%mod*C(i+j,j));
132     for(int i=0;i<=n;++i)
133         ans[i]=tmp[i][0];
134 }
135 bool used2[2333];
136 inline void solve(int S)
137 {
138     memset(wait,0,sizeof(wait));
139     queue<int>Q;
140     Q.push(S);
141     used2[S]=1;
142     int g=0;
143     while(!Q.empty())
144     {
145         int u=Q.front();
146         Q.pop();
147         dfs(u,u);
148         g=sum[u];
149         for(int i=0;i<=n;++i)
150             add(wait[i],f[u][i][0]+f[u][i][1]);
151         for(int i=head[u];i;i=E[i].next)
152         {
153             int v=E[i].to;
154             if(used2[v])
155                 continue;
156             used2[v]=1;
157             Q.push(v);
158         }
159     }
160     for(int i=0;i<g;++i)
161         wait[i]=wait[i]*qpow(g-i,mod-2)%mod;
162     assert(wait[0]==1);
163 }
164 int main()
165 {
166 //    freopen("travel.in","r",stdin);
167 //    freopen("travel.out","w",stdout);
168     ios::sync_with_stdio(false);
169     cin>>n>>m;
170     for(int i=1;i<=m;++i)
171     {
172         int x,y;
173         cin>>x>>y;
174         addE(x,y);
175         addE(y,x);
176         ++deg[x],++deg[y];
177     }
178     init();
179     ans[0]=1;
180     for(int i=1;i<=n;++i)
181         if(vis[i]&&!used[i])
182         {
183             int p=findRoot(i);
184             if(p==-1)
185                 solve(i);
186             else
187             {
188                 memset(wait,0,sizeof(wait));
189                 dfs(p,p);
190                 for(int i=0;i<=sum[p];++i)
191                     wait[i]=(f[p][i][0]+f[p][i][1])%mod;
192             }
193             update();
194         }
195     for(int i=0;i<=n;++i)
196         cout<<ans[i]<<endl;
197     return 0;
198 }
View Code

 

 posted on 2020-06-10 14:48  GreenDuck  阅读(172)  评论(0编辑  收藏  举报