北京集训DAY3
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 消去合法的序列 剩下的不合法序列一定是 ))....(((... 3 两种括号个数各加1除2 手算一下即可 4 */ 5 #include <cctype> 6 #include <cstdio> 7 #include <cstring> 8 9 const int MAXN=100010; 10 11 int len,top,cnt; 12 13 char s[MAXN]; 14 15 int hh() { 16 freopen("bracket.in","r",stdin); 17 freopen("bracket.out","w",stdout); 18 scanf("%s",s+1); 19 len=strlen(s+1); 20 for(int i=1;i<=len;++i) { 21 if(s[i]=='(') ++top; 22 else if(s[i]==')'&&top) --top; 23 else ++cnt; 24 } 25 int ans=(top+1)/2+(cnt+1)/2; 26 printf("%d\n",ans); 27 fclose(stdin); 28 fclose(stdout); 29 return 0; 30 } 31 32 int sb=hh(); 33 int main(int argc,char**argv) {;}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 维护一个f数组 f[i]表示i这个时刻 车上已经坐了几只怪兽了 3 [X,Y] Z 4 for (int i=X; i<Y; i++) 5 MAX=max(MAX,f[i]); 6 t=min(Z,M-MAX); 7 for (int i=X; i<Y; i++) f[i]+=t; 8 ans+=t 9 cout<<ans; 10 显然 可用线段树维护区间加和区间查询最大值 11 */ 12 #include<iostream> 13 #include<cmath> 14 #include<cstdio> 15 #include<cstring> 16 #include<algorithm> 17 #define N 50005 18 #define lson (root<<1) 19 #define rson (root<<1|1) 20 #define Max(a,b) a=a>b?a:b 21 using namespace std; 22 23 int k,n,m,x,y,ans,tmp,val; 24 25 int tree[N<<2],mark[N<<2]; 26 27 struct Node{ 28 int l,r,peo; 29 bool operator <(const Node &a)const { 30 if(a.r!=r)return r<a.r; 31 return l>a.l; 32 } 33 }node[N]; 34 35 inline int qread() { 36 int x=0,j=1; 37 char ch=getchar(); 38 while(ch<'0' || ch>'9'){if(ch=='-')j=-1;ch=getchar();} 39 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 40 return x*j; 41 } 42 void pushdown(int root) { 43 if(!mark[root]) return; 44 int k=mark[root]; 45 tree[lson]+=k;tree[rson]+=k; 46 mark[lson]+=k;mark[rson]+=k; 47 mark[root]=0; 48 } 49 int query(int root,int l,int r,int L,int R) { 50 if(l>R||r<L)return 0; 51 if(L<=l&&r<=R)return tree[root]; 52 int mid=(l+r)>>1; 53 pushdown(root); 54 int a=query(lson,l,mid,L,R),b=query(rson,mid+1,r,L,R); 55 tree[root]=Max(tree[lson],tree[rson]); 56 return Max(a,b); 57 } 58 void updata(int root,int l,int r,int L,int R,int to) { 59 if(l>R||r<L) return; 60 if(L<=l&&r<=R) { 61 mark[root]+=to; 62 tree[root]+=to; 63 return; 64 } 65 pushdown(root); 66 int mid=(l+r)>>1; 67 updata(lson,l,mid,L,R,to); 68 updata(rson,mid+1,r,L,R,to); 69 tree[root]=Max(tree[lson],tree[rson]); 70 } 71 int main() { 72 freopen("bus.in","r",stdin); 73 freopen("bus.out","w",stdout); 74 k=qread();n=qread();m=qread(); 75 for(int i=1;i<=k;i++) { 76 node[i].l=qread(); 77 node[i].r=qread(); 78 node[i].peo=qread(); 79 } 80 sort(node+1,node+k+1); 81 for(int i=1;i<=k;i++) { 82 tmp=query(1,1,n,node[i].l,node[i].r); 83 if(tmp>=m)continue; 84 if(tmp+node[i].peo<=m) val=node[i].peo; 85 else val=m-tmp; 86 ans+=val; 87 updata(1,1,n,node[i].l,node[i].r-1,val); 88 } 89 printf("%d\n",ans); 90 fclose(stdin);fclose(stdout); 91 return 0; 92 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 枚举左上角 n^2 枚举右下角n^2 枚举修改的数 n^2 求和 n^2 -> n^8 3 求一个矩阵和,可以通过矩阵前缀和做到O(1) 4 枚举左上角 n^2 枚举右下角n^2 枚举修改的数 n^2 -> n^6 5 预处理出每个矩阵的最小值是多少。 n^4 6 枚举左上角 n^2 枚举右下角n^2 修改的数已知(修改最小的或者不修改) -》n^4 7 n,m<=300 8 假如我们不要求修改数,查询最大子矩阵 9 有n个数,查询最大子段和 O(n) 10 for (i=1; i<=n; i++) f[i]=max(f[i-1]+a[i],a[i]); 11 max{f[i]} = 最大子段和 12 要求我们修改数 13 修改的数一定是最小的那个数。 14 f[i][0]以i结尾并且没有数被修改过的最大和 15 f[i][1]以i结尾并且有数被修改过的最大和 //a[i] 第i列的和 16 for (int i=1; i<=n; i++) 17 { 18 f[i][0]=max(f[i-1][0]+a[i],a[i]); 19 f[i][1]=max(f[i-1][1]+a[i],f[i-1][0]+a[i]-MIN[i]+P,a[i]-MIN[i]+P); 20 } 21 max{f[?][0/1]} 是答案 22 */ 23 #include <cmath> 24 #include <cstdio> 25 #include <cstdlib> 26 #include <cassert> 27 #include <algorithm> 28 29 const int INF=1000000000; 30 const int MAXN=305; 31 32 int n,m,ans,P,k; 33 34 int a[MAXN][MAXN],MIN[MAXN],b[MAXN],dp[MAXN][2],s[MAXN][MAXN]; 35 36 inline int min(int a,int b) { 37 return a>b?b:a; 38 } 39 40 inline int max(int a,int b) { 41 return a>b?a:b; 42 } 43 44 int hh() { 45 freopen("puzzle.in","r",stdin); 46 freopen("puzzle.out","w",stdout); 47 while(scanf("%d",&n)) { 48 ans=-INF; 49 scanf("%d%d",&m,&P); assert(1<=n&&n<=300&&1<=m&&m<=300&&-1000<=P&&P<=1000); 50 for(int i=1;i<=n;i++) 51 for(int j=1;j<=m;j++) {scanf("%d",&a[i][j]); assert(-1000<=a[i][j]&&a[i][j]<=1000); } 52 for(int i=1;i<=n;i++) 53 for(int j=1;j<=m;j++) 54 s[i][j]=s[i-1][j]+a[i][j]; 55 for(int i=1;i<=n;i++) { 56 for(int j=1;j<=m;j++) MIN[j]=a[i][j]; 57 for(int j=i;j<=n;j++) { 58 for(int k=1;k<=m;k++) MIN[k]=min(MIN[k],a[j][k]); 59 for(int k=1;k<=m;k++) b[k]=s[j][k]-s[i-1][k]; 60 dp[0][1]=-INF; 61 for(int k=1;k<=m;k++) dp[k][0]=max(dp[k-1][0]+b[k],b[k]),dp[k][1]=max(max(dp[k-1][1]+b[k],dp[k-1][0]+b[k]-MIN[k]+P),b[k]-MIN[k]+P); 62 for(int k=1;k<m;k++) ans=max(ans,max(dp[k][0],dp[k][1])); 63 if(i==1&&j==n) { 64 ans=max(ans,dp[m][1]); 65 int sum=0; 66 for(int k=m; k>1; k--) {sum+=b[k]; ans=max(ans,sum);} 67 } else 68 ans=max(ans,max(dp[m][1],dp[m][0])); 69 } 70 } 71 printf("%d\n",ans); 72 } 73 return 0; 74 } 75 76 int sb=hh(); 77 int main(int argc,char**argv) {;}
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现