清北学堂国庆day3解题报告

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了清北学堂国庆day3解题报告相关的知识,希望对你有一定的参考价值。

Day3解题报告

张炳琪

时间安排::

T1:15分钟

T2:想了一小时开始写写了一小时

T3:其余时间敲完,没调试

答题情况和错误分析::

T1 100

数论不会推,只能打暴力打表了60

T2100

刚开始以为是dp,没退出来,又以为是图论,然后举出了反例,然后想到活动安排的贪心,加了棵线段树维护就A

T320

分段打了三个阶段,结果第二三段的前缀和都写错了。。

 

Tot::220

 

题目解析:

T1

先去除所有配对的括号,之后讲不配对的统计数量,两种括号数量分别除以2,特盘一下是否为奇数,是的话加上二

T2

首先讲所有的路程区间按照结尾的前后排序,然后便利一边所有区间,对于每个的上车人数,取决于该段区间的最大值和区间加法,所以用个线段树维护一下就好了

T3

暴力枚举哪个点更改,当然要优先枚举值小的那些点,然后处理一个前缀和,On^3的方法求出更改后的最大子矩阵

代码::

T1:

#include<cstdio>
#include<algorithm>
#include<cstring> 
using namespace std;
char s[100010];
char sta[100010];
int top;
int ans = 0;
int main()
{
    freopen("bracket.in","r",stdin);freopen("bracket.out","w",stdout);
    scanf("%s",s);
    int len = strlen(s);
    for(int i = 0;i < len;i++)
    {
        if(s[i] == ()sta[++top] = (;
        if(s[i] == ))
        {
            if(sta[top] == ()top--;
            else
                sta[++top] = );
        }
    }
    int totl = 0;
    int totr = 0;
    for(int i = 1;i <= top;i++)
    {
        if(sta[i] == ()totl++;
        if(sta[i] == ))totr++;
    }
    ans = totl / 2 + totr / 2;
    if(totl & 1)ans += 2;
    printf("%d",ans);
    fclose(stdin);fclose(stdout);
    return 0;
}

T2

#include<cstdio>
#include<algorithm>
#include<iostream> 
using namespace std;
int tree[20010 * 10];
int maxx[20010 * 10];
int lazy[20010 * 10];
struct Edge{
    int be,ed,wei;
}edge[100010];
int read()
{
    int num = 0;
    char c = getchar();
    while(c > 9 || c < 0)c = getchar();
    while(c >= 0 && c <= 9)
    {
        num *= 10;
        num += c - 0;
        c = getchar(); 
    }
    return num;
}

bool cmp(const Edge &a,const Edge &b)
{
    return a.ed < b.ed;
}

void pushup(int x)
{
    maxx[x] = max(maxx[x << 1],maxx[x << 1 | 1]);
}

void pushdown(int x)
{
    if(lazy[x])
    {
        lazy[x << 1] += lazy[x];
        lazy[x << 1 | 1] += lazy[x];
        maxx[x << 1] += lazy[x];
        maxx[x << 1 | 1] += lazy[x];
        lazy[x] = 0;
    }
}
int ask(int l,int r,int now,int ln,int rn)
{
    if(l > rn || r < ln)return 0;
    if(l >= ln && r <= rn)
    {
        return maxx[now];
    }
    pushdown(now);
    int mid = (l + r) >> 1;
    
    int ans = max(ask(l,mid,now << 1,ln,rn),ask(mid + 1,r,now << 1 | 1,ln,rn));
    pushup(now);
    return ans;
}
void add(int l,int r,int now,int ln,int rn,int kk)
{
    if(l > rn || r < ln)return;
    if(l >= ln && r <= rn)
    {
        maxx[now] += kk;
        lazy[now] += kk;
        return;
    }
    pushdown(now);
    int mid = (l + r) >> 1;
    add(l,mid,now << 1,ln,rn,kk);
    add(mid + 1,r,now << 1 | 1,ln,rn,kk);
    pushup(now);
}


int main()
{
    freopen("bus.in","r",stdin);freopen("bus.out","w",stdout);
    int k,n,m;
    scanf("%d%d%d",&k,&n,&m);
    for(int i = 1;i <= k;i++)
    {
        edge[i].be = read();
        edge[i].ed = read();
        edge[i].wei = read();
    }    
    sort(edge + 1,edge + k + 1,cmp);
    int ans = 0;
    for(int i = 1;i <= k;i++)
    {
        int op = ask(1,n,1,edge[i].be,edge[i].ed - 1);
        int zz = min(m - op,edge[i].wei);
        ans += zz;
        add(1,n,1,edge[i].be,edge[i].ed - 1,zz);
    }
    cout << ans;
    fclose(stdin);fclose(stdout);
    return 0;    
} 
/*
3 5 3
1 3 4
3 5 2
1 5 3
ans is 5
*/
/*
5 10 7
1 5 7
2 3 6
3 4 10
5 8 6
1 10 7
ans is 19
*/
/*
10 10 12
1 2 1
1 2 1
1 2 1
1 2 1
1 3 1
1 3 1
1 3 1
1 3 1
1 10 10
5 6 1

ans is 13
*/
/*
8 10 6
1 3 3
3 5 6
1 6 6
2 3 2
4 5 4
3 4 2
1 4 3
2 5 5
ans is 14
*/
/*
10 10 6
1 10 1
1 10 1
1 10 1
1 10 3
2 9 3
2 9 3
3 8 3
3 8 3
4 6 3 
4 6 3


ans is 6



*/
/*
10 100 6
6 10 1
6 10 1
6 10 1
6 10 3
5 11 3
5 11 3
4 12 3
4 12 3
3 13 3
3 13 3
ans is 6
*/

T3

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int mp_[301][301];
int qian[301][301];
int n,m,p;
struct    hu{
    int num,x,y;    
}stack_[900000];
int col = 0;
int ans = 0;
int top = 0;
bool cmp(const hu &a,const hu &b)
{
    return a.num < b.num;
}

int main()
{
    freopen("puzzle.in","r",stdin);freopen("puzzle.out","w",stdout);
    scanf("%d%d%d",&n,&m,&p);
    for(int i = 1;i <= n;i++)
        for(int j = 1;j <= m;j++)
        {
            scanf("%d",&mp_[i][j]);    
        //    ans += mp_[i][j];
            stack_[++top].num = mp_[i][j];
            stack_[top].x = i;
            stack_[top].y = j; 
        }
    if(n <= 25)// n^6
    {
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= m;j++)
                for(int xn = i;xn <= n;xn++)
                    for(int yn = j;yn <= m;yn++)
                    {
                        int minn = 999999;
                        int tot = 0;
                        for(int ii = i;ii <= xn;ii++)
                            for(int jj = j;jj <= yn;jj++)
                                minn = min(minn,mp_[ii][jj]),tot += mp_[ii][jj];
                        if(p > minn)tot +=  (p - minn);
                        ans = max(ans,tot);
                    }
        cout<<ans;
        return 0;
    }
    if(n <= 50)//n^5
    {
        sort(stack_ + 1,stack_ + top + 1,cmp);
        for(int i = 1;i <= top;i++)
        {
            int xxx = mp_[stack_[i].x][stack_[i].y];
            if(p <= mp_[stack_[i].x][stack_[i].y])break;
            mp_[stack_[i].x][stack_[i].y] = p;
            for(int ii = 1;ii <= n;ii++)
                for(int jj = 1;jj <= m;jj++)
                {
                    qian[ii][jj] = qian[ii - 1][jj] + qian[ii][jj - 1] - qian[ii - 1][jj - 1] + mp_[ii][jj]; 
                }
            for(int ii = 1;ii <= n;ii++)
                for(int jj = ii;jj <= n;jj++)
                {
                    int as = 0;
                    for(int z = 1;z <= m;z++)
                    {
                        int op = qian[jj][z] - qian[ii - 1][z] - qian[jj][z - 1] + qian[ii - 1][z - 1];
                        if(as < 0)as = 0;
                        as += op;
                        ans = max(ans,as);
                    }
                }
            mp_[stack_[i].x][stack_[i].y] = xxx;    
        }
        cout << ans;
        return 0;
    }
    if(n <= 300)// O(看脸)
    {
        sort(stack_ + 1,stack_ + top + 1,cmp);
        if (n >100) top = 8;
        else if(n > 50)top = 25;
        else if(n > 25)top = 130;
        for(int i = 1;i <= top;i++)
        {
            int xxx = mp_[stack_[i].x][stack_[i].y];
            if(p <= mp_[stack_[i].x][stack_[i].y])break;
            mp_[stack_[i].x][stack_[i].y] = p;    
            for(int ii = 1;ii <= n;ii++)
                for(int jj = 1;jj <= m;jj++)
                {
                    qian[ii][jj] = qian[ii - 1][jj] + qian[ii][jj - 1] - qian[ii - 1][jj - 1] + mp_[ii][jj]; 
                }
            for(int ii = 1;ii <= n;ii++)
                for(int jj = ii;jj <= n;jj++)
                {
                    int as = 0;
                    for(int z = 1;z <= m;z++)
                    {
                        int op = qian[jj][z] - qian[ii - 1][z] - qian[jj][z - 1] + qian[ii - 1][z - 1];
                        if(as < 0)as = 0;
                        as += op;
                        ans = max(ans,as);
                    }
                }
            mp_[stack_[i].x][stack_[i].y] = xxx;
        }
        cout << ans;
    }
    fclose(stdin);fclose(stdout);
    return 0;
}

 

以上是关于清北学堂国庆day3解题报告的主要内容,如果未能解决你的问题,请参考以下文章

清北学堂国庆day1解题报告

清北学堂国庆day6解题报告

清北学堂国庆day7解题报告

清北学堂国庆day5解题报告

清北学堂国庆day4解题报告

2017.7.21夏令营清北学堂解题报告