金中高一康复训练6
Posted zincsabian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了金中高一康复训练6相关的知识,希望对你有一定的参考价值。
写了三道题,没有一A,不过拿了E的一血>_<
C(wa*1,re*1)
统计一下前缀和,1记为1,0记为-1,统计一下前缀和
设前缀和数组为$sum[i]$
那么就是求当$sum[i]-sum[j-1]==0$时,$i-j+1$的最大值
但是,$n<=1e6$,不过这个$sum[i]$统计到最后最大不超过1e6,所以可以用个$last[]$
因为$sum[i]-sum[j-1]==0$可以转换成求$sum[i]==sum[j-1]$
所以只要记录一下$sum[i]$最开始出现的位置就好辣>_<
但是这个$sum[i]$可能<0,所以$last[]$要开两倍空间
效率:$O(N)$
1 #include<map> 2 #include<set> 3 #include<list> 4 #include<cmath> 5 #include<queue> 6 #include<cstdio> 7 #include<vector> 8 #include<string> 9 #include<cstring> 10 #include<iostream> 11 #include<algorithm> 12 using namespace std; 13 #define mp make_pair 14 #define ll long long 15 #define reg register 16 #define inf 0x7fffffff 17 #define MOD 1000000007 18 #define clr(a) memset(a,sizeof(a),0); 19 #define rep(i,l,r) for(int i=l;i<=r;i++) 20 #define dow(i,l,r) for(int i=l;i>=r;i--) 21 inline int read(){int x=0,f=1;char c=getchar();while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}return x*f;} 22 inline ll readl(){ll x=0,f=1;char c=getchar();while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}return x*f;} 23 template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+‘0‘);} 24 template<class T>inline void writeln(T x){if(x<0)putchar(‘-‘);x=abs(x);print(x);putchar(‘ ‘);} 25 template<class T>inline void write(T x){if(x<0)putchar(‘-‘);x=abs(x);print(x);} 26 template<class T>inline T power(T a,T b){T ans=1;while(b){if(b&1){ans=ans*a%MOD;}b>>=1;a=a*a%MOD;}return ans%MOD;} 27 /*================Header Template==============*/ 28 int sum[1000005],last[2000005],ans; 29 int main(){ 30 char s[1000005]; 31 scanf("%s",s+1); int len=strlen(s+1); 32 rep(i,1,len) { 33 if(s[i]==‘1‘) sum[i]=sum[i-1]+1; 34 else sum[i]=sum[i-1]-1; 35 if(sum[i]==0) ans=max(ans,i); 36 if(last[1000000+sum[i]]) ans=max(ans,i-last[1000000+sum[i]]); 37 else last[1000000+sum[i]]=i; 38 } 39 // rep(i,1,len) cout<<sum[i]<<" "; 40 writeln(ans); 41 }
D(wa*3)
数组打少一个0,wa了三发qwq
只要,排序一下,优先把小的丢进袋子里,贪心的做
最后的答案肯定是$>=n/2$的,极端情况是前面$n/2$只袋鼠都能被塞进后面$n-n/2$只袋鼠的袋子里
那就排序一下,从$n/2$开始往下扫,和$a[n]$比较一下
注意到,如果$a[n]$放不下去,$a[n-1]$肯定放过下去
效率:$O(N)$
1 #include<map> 2 #include<set> 3 #include<list> 4 #include<cmath> 5 #include<queue> 6 #include<cstdio> 7 #include<vector> 8 #include<string> 9 #include<cstring> 10 #include<iostream> 11 #include<algorithm> 12 using namespace std; 13 #define mp make_pair 14 #define ll long long 15 #define reg register 16 #define inf 0x7fffffff 17 #define MOD 1000000007 18 #define clr(a) memset(a,sizeof(a),0); 19 #define rep(i,l,r) for(reg int i=l;i<=r;i++) 20 #define dow(i,l,r) for(reg int i=l;i>=r;i--) 21 inline int read(){int x=0,f=1;char c=getchar();while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}return x*f;} 22 inline ll readl(){ll x=0,f=1;char c=getchar();while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}return x*f;} 23 template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+‘0‘);} 24 template<class T>inline void writeln(T x){if(x<0)putchar(‘-‘);x=abs(x);print(x);putchar(‘ ‘);} 25 template<class T>inline void write(T x){if(x<0)putchar(‘-‘);x=abs(x);print(x);} 26 template<class T>inline T power(T a,T b){T ans=1;while(b){if(b&1){ans=ans*a%MOD;}b>>=1;a=a*a%MOD;}return ans%MOD;} 27 /*================Header Template==============*/ 28 int n,m,a[500005]; 29 int main(){ 30 n=read(); rep(i,1,n) a[i]=read(); sort(a+1,a+n+1); 31 m=n; 32 dow(i,n/2,1) if(a[m]>=2*a[i]) m--; 33 writeln(m); 34 }
E(wa*2)
感觉好像在bzoj见过,记得大概的写法>_<,但是这个是51nod题库的
设$?$的数量为m,替换成左括号是a[i],替换成右括号是b[i]
就,先把所有的$?$设置成$)$,$ans=sum_{i=1}^{i<=m}b[i]$
接着设所有的$($为1,所有的$)$为-1,统计一下到第i位时1~i的和是多少,设为sum
如果$sum<0$说明右括号多了>_<,那就把1~i中的一个?替换成(就好辣>_<,然后sum要+2(因为-1变成1就是+2啊)
怎么替换成$($捏,替换的代价$b[i]-a[i]$全部塞进优先队列里,优先把替换代价最大的提出来
一开始没搞懂这个wa了两发,因为你本来取的是b[i],现在取的是a[i],那么你多取了b[i]-a[[i],所以要减掉,那当然是减掉约大的ans越小啦
效率:$O(n+mlogm)$
以上是关于金中高一康复训练6的主要内容,如果未能解决你的问题,请参考以下文章
手抖康复训练1 Codeforces Global Round 6