清北学堂国庆day3解题报告
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了清北学堂国庆day3解题报告相关的知识,希望对你有一定的参考价值。
Day3解题报告
张炳琪
时间安排::
T1:15分钟
T2:想了一小时开始写写了一小时
T3:其余时间敲完,没调试
答题情况和错误分析::
T1: 100
数论不会推,只能打暴力打表了60分
T2:100
刚开始以为是dp,没退出来,又以为是图论,然后举出了反例,然后想到活动安排的贪心,加了棵线段树维护就A了
T3:20
分段打了三个阶段,结果第二三段的前缀和都写错了。。
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解题报告的主要内容,如果未能解决你的问题,请参考以下文章