// //

2019佳木斯集训 Day2

    T1

  本次考试的第一题,比较简单

  思路:每出现一个左括号就反复化为红色和蓝色

使红蓝的两种括号会最大化的分开,然后分别测定深度

取max即可

  
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int n,tip,qwq,l,r,ans;
 4 char s[200010];
 5 bool a[200010];
 6 bool color[200010];
 7 bool vis[200010];
 8 int b[200010];
 9 bool ac;
10 int main(){
11     scanf("%d",&n);
12     for(register int i=1;i<=n;i++){
13         cin>>s[i];
14         if(s[i]=='(') a[i]=1;
15         else a[i]=0;
16     }
17     for(register int i=1;i<=n;i++){
18         if(!ac&&a[i]==1) color[i]=1,ac=1,b[++qwq]=color[i];
19         else if(ac&&a[i]==1) color[i]=0,ac=0,b[++qwq]=color[i];
20         if(a[i]==0){
21             color[i]=b[++tip];
22         }
23     }
24     //for(register int i=1;i<=n;i++) printf("%d ",color[i]);
25     for(register int i=1;i<=n;i++){
26         if(color[i]==1&&a[i]==1) l++;
27         else if(color[i]==1&&a[i]==0) l--;
28         else if(color[i]==0&&a[i]==1) r++;
29         else if(color[i]==0&&a[i]==0) r--;
30         ans=max(ans,max(l,r));
31     }
32     printf("%d",ans);
33     return 0;
34 }
T1-Problem 1

    T2

  本次考试的最难题(我认为滴~)

  思路:随便找一个点作为根节点,把以所有点为根的子树

大小求出来,以上用一个深搜实现,然后再用一个深搜,以根节点

的每一个子节点假设为真实的出发点我们还可以发现一个式子

就是总点数-当前的子树大小*2是ans的增量,所以下一个深搜就

搞这件事就可以了

  
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 struct node{
 4     int nxt,to;
 5 }edge[2000010];
 6 int head[2000010];
 7 int n,x,y,cnt;
 8 long long ans;
 9 long long ac=2;
10 int tree[2000010];
11 inline void addedge(int from,int to){
12     cnt++;
13     edge[cnt].to=to;
14     edge[cnt].nxt=head[from];
15     head[from]=cnt;
16 }
17 void dfs(int now,int before){
18     tree[now]=1;
19     for(register int i=head[now];i;i=edge[i].nxt){
20         if(edge[i].to==before) continue;
21         dfs(edge[i].to,now);
22         tree[now]+=tree[edge[i].to]; 
23     }
24 }
25 void true_ans(int now,int before,long long nowans){
26     ans=max(ans,nowans);
27     for(register int i=head[now];i;i=edge[i].nxt){
28         if(edge[i].to==before) continue;
29         true_ans(edge[i].to,now,nowans+n-ac*tree[edge[i].to]);
30     }
31 }
32 int main(){
33     scanf("%d",&n);
34     for(register int i=1;i<n;i++){    
35         scanf("%d%d",&x,&y);
36         addedge(x,y);
37         addedge(y,x);
38     }
39     dfs(1,0);
40     for(register int i=1;i<=n;i++) ans+=tree[i];
41     true_ans(1,0,ans);
42     printf("%lld",ans);
43     return 0;
44 }
T2-Problem 2

    T3

  不算非常难的一道题,但是有很多细节,而且有玄学的错误!!!

(以后long long用位运算注意点!!)

  思路:每输入一辆车,就二分求一下车需要的最小油量,然后

等所有的点都求完再取最小值的最大值即可

  
 1 #include <bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 int n,m;
 5 int a[500];
 6 int s,f,c,r,trueans;
 7   
 8 inline bool check(int x){
 9     int xx=x,rr=0;
10     for(register int j=s+1;j<=f;j++){
11         if(xx<(a[j]-a[j-1])*c) rr++,xx=x;
12         if(rr>r) return false;
13         xx-=(a[j]-a[j-1])*c;
14     }
15     return true;
16 }
17 int ef(int L,int R){
18     if(R==L) return L;
19     int mid=L+R;
20     mid/=2;
21     if(check(mid)) return ef(L,mid);
22     else return ef(mid+1,R);
23 }
24 signed main()
25 {
26     scanf("%lld%lld",&n,&m);
27     for(register int i=1;i<=n;i++) scanf("%lld",&a[i]);
28     for(register int i=1;i<=m;i++)
29     {
30         int ac=0,nowans=0;
31         scanf("%lld%lld%lld%lld",&s,&f,&c,&r);
32         if(trueans&&check(trueans))continue;
33         for(register int j=s+1;j<=f;j++)ac=max(a[j]-a[j-1],ac);
34         nowans=ef(ac*c,(a[f]-a[s])*c);
35         trueans=max(trueans,nowans);
36     }
37     printf("%lld\n",trueans);
38 }
T3-Problem 3

  Day2  score:100  rank 22

  end;

posted @ 2019-07-27 20:58  Zafkiel  阅读(128)  评论(0编辑  收藏  举报
Live2D //博客园自带,可加可不加