佳木斯集训Day2

D2好点了,最起码不像之前那么水

T1按照常规操作是个找规律,类似于括号匹配的题,但是又不是,推进栈里,然后看最长的左括号有多少个,然后直接cout就可以了

#include <bits/stdc++.h>
using namespace std;
int n,point,ans=-1;
char a[1000050];
stack <char>s;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        s.push(a[i]);
        if(s.top()=='(')
        point++;
        else
        s.pop(),point--;
        ans=max(ans,point);
    }
    if(ans%2==1)
    cout<<ans/2+1<<endl;
    else
    cout<<ans/2<<endl;
}
View Code

哎,居然可以折叠代码,我才发现

 

T2本来以为是个搜索,结果正解就是个搜索,dfs+一个简单的找规律,咳咳,看完题解就会了

不知道为什么,这道题我爆0了

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int t,head[300500],x,y,n,in[300500],ans[300500];
int point=0;
ll sum;
struct Tree{
    int v,nxt;
}g[400500];
void add(int u,int v)
{
    g[++point].v=v;
    g[point].nxt=head[u];
    head[u]=point;
}
void dfs(int x,int nw)
{
    ans[x]=1;
    for(int i=head[x];i;i=g[i].nxt)
    {
        if(g[i].v==nw)continue;
        dfs(g[i].v,x);
        ans[x]+=ans[g[i].v];
    }
    sum+=ans[x];
}
void solve(int x,int square,ll nw)
{
    sum=max(sum,nw);
    for(int i=head[x];i;i=g[i].nxt)
    {
        if(g[i].v==square)
        continue;
        solve(g[i].v,x,nw+n-2LL*ans[g[i].v]);
    }
}
int main()
{
    memset(head,0,sizeof(head));
    cin>>n;
    for(int i=1;i<=n-1;i++)
    {
        cin>>x>>y;
        add(x,y);
        add(y,x);
        in[x]++;
        in[y]++;
    }
    dfs(1,0);
    solve(1,0,sum);
    cout<<sum<<endl;
    return 0;
}
View Code

 

T3 是个神奇的二分答案,加上了一个神奇的剪枝就能AC,然而蒟蒻的我并没有想到剪枝,所以我RE60

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 ll n,m,ans=0;
 5 ll c;
 6 ll pos[450];
 7 ll start,finish,admit,dis,maxn;
 8 bool Black(ll k)
 9 {
10     ll v=k;
11     ll point=0;
12     for(ll i=start;i<finish;i++)
13     {
14         if(k<(pos[i+1]-pos[i])*c)
15         return 0;
16         if(v<(pos[i+1]-pos[i])*c)
17         {
18             v=k;
19             point++;
20         }       
21         v=v-(pos[i+1]-pos[i])*c;
22         if(point>admit||v<0)
23         return 0;
24     }
25     return 1;
26 } 
27 void divide(ll l,ll r)
28 {
29     if(l==r) 
30     {
31          
32         ans=max(ans,l);
33         //cout<<ans<<endl;
34         return ;    
35     }
36     ll mid=(l+r)/2;
37     if(Black(mid)==1)
38     divide(l,mid);  
39     else
40     divide(mid+1,r);
41 }
42 int main()
43 {
44     cin>>n>>m;
45     for(ll i=1;i<=n;i++)
46     cin>>pos[i];
47     for(ll i=1;i<=m;i++)
48     {
49         cin>>start>>finish>>c>>admit;
50         if(ans&&Black(ans))
51         continue;
52         divide(1,1e18);
53     }
54     cout<<ans<<endl;
55     return 0;
56 }
View Code

 

posted @ 2019-08-06 14:49  落筱  阅读(106)  评论(0编辑  收藏  举报