快要考试了我还是这么菜。

已经没有心思维护我的博客了。开一篇博文吧。可能会记得很乱。

这也许是我OI生涯的最后一篇博文了??

肯定很长很长。

不可能的。谁知道什么时候我心态恢复就把上面两句话删掉开始在博客里各种胡咧咧了。

好,我心态恢复了。我要写日记了hhh


「$idea$」维护凸包

临考前才学必定致命。

主要因为昨天考了一套题,T1是凸包。%%%$OOO$李超线段树怒切T1。

我要澄清一下,关于$OOO$大神在李超线段树的学习笔记中提到本人,

本人对此严正声明:我不会李超线段树。我只是颓废,大神一直在学习。

至于他会不会发布这篇笔记我不清楚。

上面是废话

凸包其实是个非常简单的东西。之前一直觉得特别难。

其实之前有一次临时决定强行学习一波,打开一个学习笔记,第一眼:叉积。

告辞。

然后发现,其实只需要对斜率排个序,求个交点,单队或者单调栈维护一下就行了。

「$idea$」树的遍历

谁也不知道我为什么突然脑抽去看树的遍历。。。

实际上并没有什么用处。。。

放个链接:树的遍历

「题解」笨小猴:结论题

赛时$random\_shuffle$本来能$AC$。

结果统计总和没开$long$ $long$,$OJ$测拿了$20$,$lemon$测拿了50。

$lemon$测比$OJ$测高也是创了个记录。

简要题解:

把所有卡片按照$A$的大小排序。然后从左到右每两张卡片分成一组,我们选取每组中$B$较大的,再将最后一张卡片选取即可。

证明:最坏的情况无非两两一组中总是$A$较小的那个$B$较大。此时我们换一种分组方式,把$1$提出来,$2,3$一组,以此类推就全是$A$较大的那个$B$较大了。

所以没有$-1$情况。

代码:

这个是$random\_shuffle$的。

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define rint register int
  4. using namespace std;
  5. inline void read(int &a)
  6. {
  7. a=0;int b=1;char ch=getchar();
  8. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  9. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  10. a=a*b;return ;
  11. }
  12. int n,a[200005],b[200005],Suma,Sumb,ans[100005],tim,id[200005];
  13. inline void dfs(int k,int gt,int suma,int sumb)
  14. {
  15. if(gt==n+1)
  16. {
  17. if(suma>Suma-suma&&sumb>Sumb-sumb)
  18. {
  19. for(rint i=1;i<=gt;++i)
  20. printf("%d\n",ans[i]);
  21. exit(0);
  22. }
  23. return ;
  24. }
  25. if(k==2*n+2)return ;
  26. dfs(k+1,gt,suma,sumb);ans[gt+1]=k;
  27. dfs(k+1,gt+1,suma+a[k],sumb+b[k]);
  28. return ;
  29. }
  30. signed main()
  31. {
  32. freopen("grandmaster.in","r",stdin);
  33. freopen("grandmaster.out","w",stdout);
  34. srand(time(NULL));
  35. tim=clock();read(n);
  36. for(rint i=1;i<=2*n+1;++i)
  37. {
  38. read(a[i]),read(b[i]);
  39. Suma+=a[i],Sumb+=b[i],id[i]=i;
  40. }
  41. if(n<=10){dfs(1,0,0,0);puts("-1");return 0;}
  42. while(1)
  43. {
  44. if(clock()-tim>940000)break;
  45. random_shuffle(id+1,id+2*n+1);
  46. int sa=0,sb=0;
  47. for(rint i=1;i<=n+1;++i)
  48. sa+=a[id[i]],sb+=b[id[i]];
  49. if(sa>Suma-sa&&sb>Sumb-sb)
  50. {
  51. for(rint i=1;i<=n+1;++i)
  52. printf("%d\n",id[i]);
  53. return 0;
  54. }
  55. }
  56. puts("-1");return 0;
  57. }

这个是正解。

  1. #include<bits/stdc++.h>
  2. #define rint register int
  3. using namespace std;
  4. inline void read(int &a)
  5. {
  6. a=0;int b=1;char ch=getchar();
  7. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  8. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  9. a=a*b;return ;
  10. }
  11. int n,ans[100005],tim,id[200005];
  12. struct node{int a,b,id;}pi[200005];
  13. inline bool cmp(node A,node B){return A.a<B.a;}
  14. int main()
  15. {
  16. freopen("grandmaster.in","r",stdin);
  17. freopen("grandmaster.out","w",stdout);
  18. read(n);
  19. for(rint i=1;i<=2*n+1;++i)
  20. read(pi[i].a),read(pi[i].b),pi[i].id=i;
  21. sort(pi+1,pi+2*n+1+1,cmp);
  22. for(rint i=1;i<=n;++i)
  23. {
  24. if(pi[(i<<1)-1].b<=pi[i<<1].b)
  25. printf("%d\n",pi[i<<1].id);
  26. else printf("%d\n",pi[(i<<1)-1].id);
  27. }
  28. printf("%d\n",pi[2*n+1].id);
  29. return 0;
  30. }

「题解」开心的金明:贪心+模拟

我没看出来这道题和金明有半毛钱关系。。。办公司的不是小木么。。。

简要题解:

贪心。不想证明。

电脑能造多少造多少,大不了不卖都扔掉。卖电脑的时候选成本最小的卖掉,成本大的可以退掉。

然后就没了。维护两个小根堆来回捯完事了。

注意别一个电脑一个电脑的模拟,会T60。一组一组得处理。

代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define rint register int
  4. using namespace std;
  5. const int N=50004,inf=0x7fffffff;
  6. inline void read(int &a)
  7. {
  8. a=0;int b=1;char ch=getchar();
  9. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  10. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  11. a=a*b;return ;
  12. }
  13. int n,ci[N],di[N],pi[N],mi[N],ei[N],ri[N],gi[N];
  14. int yt[N],ccf[N],ycb[N],ck[N],now,sum,ans;
  15. struct node{int wi,num;};
  16. bool operator < (node A,node B){
  17. return A.wi>B.wi;
  18. }
  19. priority_queue<node> q[2];
  20. signed main()
  21. {
  22. freopen("happy.in","r",stdin);
  23. freopen("happy.out","w",stdout);
  24. read(n);ci[0]=inf;memset(ycb,0x7f,sizeof(ycb));
  25. for(rint i=1;i<=n;++i)read(ci[i]),read(di[i]),read(mi[i]),read(pi[i]);
  26. for(rint i=1;i<n;++i)read(ei[i]),read(ri[i]),read(gi[i]),ccf[i+1]=ccf[i]+ri[i];
  27. for(rint i=1;i<=n;++i)
  28. {
  29. if(ci[yt[i-1]]+ccf[i]-ccf[yt[i-1]]<ycb[i])
  30. ycb[i]=ci[yt[i-1]]+ccf[i]-ccf[yt[i-1]],yt[i]=yt[i-1];
  31. if(ci[i]<ycb[i])yt[i]=i,ycb[i]=ci[i];
  32. }
  33. for(rint i=1;i<=n;++i,now^=1)
  34. {
  35. if(sum+pi[i]<di[i])return puts("-1"),0;
  36. q[now].push((node){ycb[i]+mi[i],pi[i]});
  37. int lin=0;
  38. while(lin+q[now].top().num<=di[i])
  39. ans+=q[now].top().num*q[now].top().wi,lin+=q[now].top().num,q[now].pop();
  40. if(lin<di[i])
  41. {
  42. int dwi=q[now].top().wi,dnum=q[now].top().num,lst=di[i]-lin;
  43. ans+=lst*dwi;q[now].pop();q[now].push((node){dwi,dnum-lst});
  44. }
  45. while(q[!now].size())q[!now].pop();
  46. lin=sum=0;
  47. while((!q[now].empty())&&lin+q[now].top().num<=ei[i])
  48. {
  49. q[!now].push((node){q[now].top().wi+gi[i],q[now].top().num});
  50. lin+=q[now].top().num,sum+=q[now].top().num,q[now].pop();
  51. }
  52. if(lin<ei[i]&&(!q[now].empty()))
  53. {
  54. int dwi=q[now].top().wi,dnum=q[now].top().num,lst=ei[i]-lin;
  55. q[!now].push((node){dwi+gi[i],lst});sum+=lst;
  56. }
  57. }
  58. printf("%lld\n",ans);
  59. return 0;
  60. }

「题解」陶陶摘苹果:线段树+二分+单调栈

我们熟悉陶陶摘苹果,苹果摘陶陶,这次陶陶再次来摘苹果了,是排序还是贪心,是迪利克雷卷积还是快速傅里叶变换。

我说我没看出来线段树维护单调栈你信么。。。考场上自己yy了一个$O(nlog^2n)$的做法。

简要题解:

可以发现,对于一个位置的改变,最终答案可以拆成两部分:该位置前的和该位置后的。

我们可以考虑先在原本的序列上跑一遍答案,记录下来答案路径,然后用线段树记录区间最大值和区间最大值第一次出现的位置,还要跑一遍单调栈维护出所有节点到最后的上升序列长度。

对于这个位置以前的部分,有一个显然的性质是这一部分的区间最大值第一次出现的位置一定在答案路径上。

我更改的是它后面的值,不会对它的答案路径产生影响。所以直接继承过来到它的答案路径长度。

如果我当前更改的值要大于前一部分的最大值,则当前节点也在本次更改的答案路径上。ans++,区间最大值要更新为当前修改值。

对于后一部分,二分找到第一个比当前值要大的值的位置,答案加上这个位置到最后的上升序列长度即可。

代码:

  1. #include<bits/stdc++.h>
  2. #define rint register int
  3. using namespace std;
  4. const int inf=0x7fffffff;
  5. inline void read(int &a)
  6. {
  7. a=0;int b=1;char ch=getchar();
  8. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  9. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  10. a=a*b;return ;
  11. }
  12. int n,m,h[100005];
  13. int t[100005<<5],loc[100005<<5];
  14. int sta[100005],tp,bop[100005],len[100005];
  15. int ky[100005],rd[100005],cnt;
  16. inline void update(int k)
  17. {
  18. t[k]=max(t[k<<1],t[k<<1|1]);
  19. if(t[k]==t[k<<1])loc[k]=loc[k<<1];
  20. else loc[k]=loc[k<<1|1];
  21. }
  22. inline void build(int k,int l,int r)
  23. {
  24. if(l==r){t[k]=h[l],loc[k]=l;return ;}
  25. int mid=(l+r)>>1;
  26. build(k<<1,l,mid);
  27. build(k<<1|1,mid+1,r);
  28. update(k);return ;
  29. }
  30. inline void change(int k,int l,int r,int p,int dat)
  31. {
  32. if(l==r){t[k]=dat;return ;}
  33. int mid=(l+r)>>1;
  34. if(p<=mid)change(k<<1,l,mid,p,dat);
  35. else change(k<<1|1,mid+1,r,p,dat);
  36. update(k);return ;
  37. }
  38. inline void query(int k,int l,int r,int L,int R,int &res,int &lc)
  39. {
  40. if(R<L)return res=0,lc=0,void();
  41. if(L<=l&&r<=R){if(t[k]>res)res=t[k],lc=loc[k];return ;}
  42. int mid=(l+r)>>1;
  43. if(L<=mid)query(k<<1,l,mid,L,R,res,lc);
  44. if(R>mid)query(k<<1|1,mid+1,r,L,R,res,lc);
  45. return ;
  46. }
  47. inline int ef(int st,int dat)
  48. {
  49. int l=st,r=n+1;
  50. while(l<r)
  51. {
  52. int mid=(l+r)>>1,res=0,lc=0;
  53. query(1,1,n,st,mid,res,lc);
  54. if(res<=dat)l=mid+1;
  55. else r=mid;
  56. }
  57. return len[l];
  58. }
  59. int main()
  60. {
  61. freopen("TaoPApp.in","r",stdin);
  62. freopen("TaoPApp.out","w",stdout);
  63. read(n),read(m);h[0]=inf;
  64. for(rint i=1;i<=n;++i)read(h[i]);
  65. if(n<=5000&&m<=5000)
  66. {
  67. for(rint i=1,p,hp,tp,lin,ans;i<=m;++i)
  68. {
  69. read(p),read(hp);tp=h[p],h[p]=hp;
  70. lin=ans=0;
  71. for(rint j=1;j<=n;++j)
  72. if(h[j]>lin)lin=h[j],ans++;
  73. printf("%d\n",ans);h[p]=tp;
  74. }
  75. return 0;
  76. }
  77. build(1,1,n);
  78. for(rint i=1;i<=n;++i)
  79. {
  80. while(h[sta[tp]]<h[i])bop[sta[tp--]]=i;
  81. sta[++tp]=i;
  82. }
  83. for(rint i=n;i>=1;--i)len[i]=len[bop[i]]+1;
  84. int mxp=0;
  85. for(rint i=1;i<=n;++i)
  86. if(h[i]>mxp)mxp=h[i],rd[++cnt]=i,ky[i]=cnt;
  87. for(rint i=1,p,hp,ans;i<=m;++i)
  88. {
  89. read(p),read(hp);ans=0;
  90. int res=0,lc=0,tag=hp;
  91. query(1,1,n,1,p-1,res,lc);
  92. ans=ky[lc];
  93. (res>=hp)?tag=res:ans++;
  94. ans+=ef(p+1,tag);
  95. printf("%d\n",ans);
  96. }
  97. return 0;
  98. }

「题解」求和:等差数列求和公式

$sb$等差数列求和公式,取模后再除以2挂了$70$分神白名列。

改了半天没改过,请$Wang\_hecao$大佬帮我$debug$了一下。

还有C承担两次除法这种操作??

简要题解:

$sb$等差数列求和公式。

取模后不能做除法运算。取模后不能做除法运算。取模后不能做除法运算。

代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define rint register int
  4. using namespace std;
  5. inline void read(int &a)
  6. {
  7. a=0;int b=1;char ch=getchar();
  8. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  9. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  10. a=a*b;return ;
  11. }
  12. int l,u,r,d,mod,A,B,C,ans,flag=0;
  13. inline int qpow(int a,int b)
  14. {
  15. int sum=1;
  16. while(b){if(b&1)sum=sum*a%mod;a=a*a%mod;b>>=1;}
  17. return sum;
  18. }
  19. inline int multi(int a,int b)
  20. {
  21. int sum=0;
  22. while(b){if(b&1)sum=(sum+a)%mod;a=(a+a)%mod;b>>=1;}
  23. return sum;
  24. }
  25. signed main()
  26. {
  27. freopen("sum.in","r",stdin);
  28. freopen("sum.out","w",stdout);
  29. read(l),read(u),read(r),read(d),read(mod);
  30. A=r-l+1;B=d-u+1;C=l+u+r+d-2;
  31. if(A%2==0)A/=2,flag++;
  32. if(B%2==0&&!flag)B/=2,flag++;
  33. if(C%2==0&&!flag)C/=2,flag++;
  34. A%=mod;B%=mod;C%=mod;
  35. ans=multi(multi(A,B),C)%mod;
  36. printf("%lld\n",ans);
  37. return 0;
  38. }

「题解」分组配对:倍增+二分

赛时开了4个手写栈,最坏时间复杂度$O(n^2)$水了75分,一直觉得带上二分是$O(n^2log)$的结果人家有85-90的好成绩。。

感谢lyl大佬带我重新认识二分。这个世界上没有普适的二分板子.jpg。

简要题解:

倍增判定范围,二分确定具体分界点,可以保证时间复杂度稳定为$O(nlog^2n)$

代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define rint register int
  4. using namespace std;
  5. inline void read(int &a)
  6. {
  7. a=0;int b=1;char ch=getchar();
  8. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  9. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  10. a=a*b;return ;
  11. }
  12. int n,m,a[500005],b[500005],sum;
  13. int male[500005],female[500005];
  14. inline bool check(int lb,int rb)
  15. {
  16. int res=0;
  17. for(rint i=lb;i<=rb;++i)male[i]=a[i],female[i]=b[i];
  18. sort(male+lb,male+rb+1);sort(female+lb,female+rb+1);
  19. for(rint i=lb;i<=rb;++i)res+=male[i]*female[i];
  20. return res<m;
  21. }
  22. inline int work(int st,int l,int r)
  23. {
  24. while(l<r)
  25. {
  26. int mid=(l+r+1)>>1;
  27. if(check(st,mid))l=mid;
  28. else r=mid-1;
  29. }
  30. return l;
  31. }
  32. signed main()
  33. {
  34. freopen("pair.in","r",stdin);
  35. freopen("pair.out","w",stdout);
  36. read(n),read(m);
  37. for(rint i=1;i<=n;++i)read(a[i]);
  38. for(rint i=1;i<=n;++i)read(b[i]);
  39. int st=1,en=1;
  40. while(st<=n)
  41. {
  42. int pos=1;
  43. for(;st+pos<n;pos<<=1)
  44. if(!check(st,st+pos))break;
  45. st=work(st,st+(pos>>1),min(st+pos,n))+1,sum++;
  46. }
  47. printf("%lld\n",sum);
  48. return 0;
  49. }

「题解」真相:预处理

赛时一直考虑如何正着推理然后就死了。

简要题解:

一个比较暴力的想法是枚举说「真」话的人数,枚举每一个意淫预言家,可以直接知道$ta$说的「真」$or$「假」,由此向上(逆时针)可以一直推到上一个预言家。

优化可以考虑直接预处理每个预言家到上一个预言家的区间,处理内容为当前预言家说话为「真」时区间内说真话的人数和当前预言家说话为「假」时区间内说真话的人数。然后按预言家的预言内容存储人数。由于同时最多只有一种预言家说的是真话,所以可以$O(1)$查询这种预言家说真话时说真话的人数,于是我们先自己预言所有预言家说的都是错的,直接统计所有预言家均说假话时说真话的人数,当查询每一种预言家的时候直接减去这种预言家说假话时说真话的人数,加上这种预言家说真话时说真话的人数即可。

代码:

  1. #include<bits/stdc++.h>
  2. #define rint register int
  3. using namespace std;
  4. inline void read(int &a)
  5. {
  6. a=0;int b=1;char ch=getchar();
  7. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  8. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  9. a=a*b;return ;
  10. }
  11. int T,n,cnt[2][1000006],as[1000006];char ch[3];bool te=0;
  12. vector <int> v;
  13. struct node{int opt,wi;}h[1000006];
  14. inline int lst(rint x){return (x==1)?n:x-1;}
  15. int main()
  16. {
  17. freopen("truth.in","r",stdin);
  18. freopen("truth.out","w",stdout);
  19. read(T);
  20. while(T--)
  21. {
  22. read(n);te=0;v.clear();
  23. for(rint i=1;i<=n;++i)
  24. {
  25. scanf("%s",ch);
  26. switch(ch[0])
  27. {
  28. case '+':h[i].opt=1;break;
  29. case '-':h[i].opt=2;break;
  30. case '$':
  31. h[i].opt=3;read(h[i].wi);te=1;
  32. v.push_back(i);break;
  33. }
  34. }
  35. if(!te)
  36. {
  37. int tag=0;
  38. for(rint i=1;i<=n;++i)
  39. {
  40. if(tag==0&&h[i].opt==1){tag=0;continue;}
  41. if(tag==0&&h[i].opt==2){tag=1;continue;}
  42. if(tag==1&&h[i].opt==1){tag=1;continue;}
  43. if(tag==1&&h[i].opt==2){tag=0;continue;}
  44. }
  45. if(tag==0){puts("consistent");continue;}
  46. else{puts("inconsistent");continue;}
  47. }
  48. else
  49. {
  50. for(rint i=0;i<=n;++i)cnt[0][i]=cnt[1][i]=0;
  51. int ans=0;
  52. for(rint j=0;j<v.size();++j)
  53. {
  54. int sum=0;
  55. int lin=v[j],tag=0;
  56. int loc=lin,lt=lst(lin);
  57. while(h[lt].opt!=3)
  58. {
  59. if(tag==0&&h[lt].opt==1)tag=0;
  60. else if(tag==0&&h[lt].opt==2)tag=1,sum++;
  61. else if(tag==1&&h[lt].opt==1)tag=1,sum++;
  62. else if(tag==1&&h[lt].opt==2)tag=0;
  63. loc=lt,lt=lst(loc);
  64. }
  65. cnt[0][h[lin].wi]+=sum;
  66. }
  67. for(rint j=0;j<v.size();++j)
  68. {
  69. int sum=1;
  70. int lin=v[j],tag=1;
  71. int loc=lin,lt=lst(lin);
  72. while(h[lt].opt!=3)
  73. {
  74. if(tag==0&&h[lt].opt==1)tag=0;
  75. else if(tag==0&&h[lt].opt==2)tag=1,sum++;
  76. else if(tag==1&&h[lt].opt==1)tag=1,sum++;
  77. else if(tag==1&&h[lt].opt==2)tag=0;
  78. loc=lt,lt=lst(loc);
  79. }
  80. cnt[1][h[lin].wi]+=sum;
  81. }
  82. for(rint i=0;i<=n;++i)ans+=cnt[0][i];
  83. for(rint i=0;i<=n;++i)
  84. {
  85. ans-=cnt[0][i];ans+=cnt[1][i];
  86. if(ans==i){puts("consistent");goto skyhecao;}
  87. ans+=cnt[0][i];ans-=cnt[1][i];
  88. }
  89. puts("inconsistent");
  90. skyhecao: continue;
  91. }
  92. }
  93. }
  94. /*
  95. 3
  96. 3
  97. +
  98. +
  99. $ 3
  100. 3
  101. +
  102. -
  103. $ 3
  104. 1
  105. -
  106. */

「题解」格式化:排序题、贪心

简要题解:

所以我不会做排序题。赛时xjb写了三个排序加上$random_shuffle$水到了80分hhh。

正解排序方式:分个类,先格式化有收益的,有收益的按格式化之前的空间排序,有损耗的按照格式化之后的空间排序。前后一致的放中间。

代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define Online_Judge
  4. //#define dp
  5. #define rint register int
  6. using namespace std;
  7. inline void read(int &a)
  8. {
  9. a=0;int b=1;char ch=getchar();
  10. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  11. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  12. a=a*b;return ;
  13. }
  14. int n,ans=0x7fffffffffffffff,res=0,space=0,tim=0;
  15. struct node{int st,en;}pan[2000006];
  16. inline bool cmp(node A,node B)
  17. {
  18. if(A.st<A.en&&B.st<B.en)return A.st<B.st;
  19. if(A.st>A.en&&B.st>B.en)return A.en>B.en;
  20. if(A.st>A.en&&B.st<B.en)return false;
  21. if(A.st<A.en&&B.st>B.en)return true;
  22. if(A.st<A.en&&B.st==B.en)return true;
  23. if(A.st>A.en&&B.st==B.en)return false;
  24. if(A.st==A.en&&B.st<B.en)return false;
  25. if(A.st==A.en&&B.st>B.en)return true;
  26. return A.en+A.st<B.en+B.st;
  27. }
  28. signed main()
  29. {
  30. #ifdef dp
  31. freopen("4.in","r",stdin);
  32. freopen("3.out","w",stdout);
  33. #endif
  34. #ifdef Online_Judge
  35. freopen("reformat.in","r",stdin);
  36. freopen("reformat.out","w",stdout);
  37. #endif
  38. read(n);
  39. for(rint i=1;i<=n;++i)
  40. read(pan[i].st),read(pan[i].en);
  41. res=0;space=0;
  42. sort(pan+1,pan+n+1,cmp);
  43. for(rint i=1;i<=n;++i)
  44. {
  45. if(pan[i].st>space)
  46. {
  47. res+=pan[i].st-space;
  48. space=pan[i].en;
  49. }
  50. else
  51. {
  52. space-=pan[i].st;
  53. space+=pan[i].en;
  54. }
  55. }
  56. ans=min(ans,res);
  57. printf("%lld\n",ans);
  58. return 0;
  59. }

「$idea$」$\mathcal{Chebyshev}$ $\mathcal{Distance}$ $\&$ $\mathcal{Manhattan}$ $\mathcal{Distance}$

切比雪夫距离与曼哈顿距离关系密切,因为它们可以相互转化。

切比雪夫转曼哈顿:$(x,y)->(\frac{x+y}2 , \frac{x-y}2)$

曼哈顿转切比雪夫:$(x,y)->(x+y,x-y)$

例题:$[TJOI2013]$松鼠聚会

题目大意:给出一个坐标系上的一些点为松鼠的家,定义点与点之间的距离为切比雪夫距离,求所有松鼠都到一个松鼠家里去所走的最小路径长度和。数据范围$n \leq 1e5 , |x|,|y| \leq 1e9$

题解:

先将原坐标系上的点$(x,y)$转化为$(x,y)->(\frac{x+y}2 , \frac{x-y}2)$,

原图上的切比雪夫距离随即转化为新图的曼哈顿距离。

答案就变成了$min{\sum\limits_{j=1}^n|x_i-x_j| + \sum\limits_{j=1}^n|y_i-y_j|}$

此时我们考虑分别对$x$和$y$排序,可以直接把绝对值去掉。

化简可得

$min\{(i-1)*x_i - \sum\limits_{j=1}^{i-1} x_j + \sum\limits_{j=i+1}^n x_j - (n-i)*x_i + i*y_i - \sum\limits_{j=1}^i y_j + \sum\limits_{j=i+1}^n y_j - (n-i)*y_i\}$

前缀和优化即可。

p.s.上面这个柿子我手打的,有什么错大家一定要指出来呀……

代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define rint register int
  4. using namespace std;
  5. inline void read(int &a)
  6. {
  7. a=0;int b=1;char ch=getchar();
  8. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  9. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  10. a=a*b;return ;
  11. }
  12. int n,ans=0x7fffffffffffffff;
  13. int sxfrt[100005],sxbak[100005],syfrt[100005],sybak[100005],inx[100005],iny[100005];
  14. int x[100005],y[100005];
  15. signed main()
  16. {
  17. // freopen("1.in","r",stdin);
  18. // freopen("1.out","w",stdout);
  19. read(n);
  20. for(rint i=1,stx,sty;i<=n;++i)
  21. {
  22. read(stx),read(sty);
  23. x[i]=inx[i]=stx+sty;
  24. y[i]=iny[i]=stx-sty;
  25. }
  26. sort(x+1,x+n+1);
  27. sort(y+1,y+n+1);
  28. for(rint i=1;i<=n;++i)
  29. {
  30. sxfrt[i]=sxfrt[i-1]+x[i],
  31. syfrt[i]=syfrt[i-1]+y[i];
  32. }
  33. for(rint i=n;i>=1;--i)
  34. {
  35. sxbak[i]=sxbak[i+1]+x[i],
  36. sybak[i]=sybak[i+1]+y[i];
  37. }
  38. for(rint i=1;i<=n;++i)
  39. {
  40. int res=0;
  41. int res1=lower_bound(x+1,x+n+1,inx[i])-x;
  42. int res2=lower_bound(y+1,y+n+1,iny[i])-y;
  43. res+=(res1-1)*inx[i]-sxfrt[res1-1]+sxbak[res1+1]-(n-res1)*inx[i];
  44. res+=(res2-1)*iny[i]-syfrt[res2-1]+sybak[res2+1]-(n-res2)*iny[i];
  45. ans=min(ans,res);
  46. }
  47. printf("%lld\n",ans>>1);
  48. return 0;
  49. }

「非知识性失分」赛后收文件前「胡乱」更改文件

额,这个正式比赛应该不会存在问题。不过毕竟是校内比赛。。。

说一下痛苦的过程:

赛时的文件有人的没有收上来,老师就重新收了一遍。

然而收上去的是我赛后写的一个用来测试long double的代码。。。

为了图方便我直接在主目录的文件上更改的。于是60->0。


「题解」二叉搜索树:区间dp+剪枝

发现O(n^3)的暴力dp还是挺好想的。然而赛时我就是被模拟蒙蔽了双眼。

简要题解:

区间dp的一般形式:设$f_{i,j}$表示只考虑区间$i$到$j$的答案。

转移只需要在$i$到$j$之间枚举转移点$k$,使得$k$为区间$i$到$j$形成二叉搜索树的根节点。

转移方程:$f_{i,j}=f_{i,k-1}+f_{k+1,j}+\sum\limits_{l=i}^j x_i$。

优化:归纳证明可得上述转移存在决策单调性,所以我们记录一下每个区间的上一个转移点,枚举转移点的时候在$[i,j-1]$和$[i+1,j]$的转移点之间枚举即可。

中间出了一点小$bug$,就是说枚举$k$的时候会出现$k+1>n$的情况,不处理会$w70$,初始化一下不合法区间就可以了。

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define rint register int
  4. using namespace std;
  5. inline void read(int &a)
  6. {
  7. a=0;int b=1;char ch=getchar();
  8. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  9. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  10. a=a*b;return ;
  11. }
  12. int n,x[5003],f[5003][5003],sum[5003],g[5003][5003];
  13. signed main()
  14. {
  15. read(n);memset(f,0x3f,sizeof(f));
  16. for(rint i=1;i<=n;++i)
  17. {
  18. read(x[i]),sum[i]=sum[i-1]+x[i];
  19. f[i][i]=x[i],g[i][i]=i;
  20. for(rint j=0;j<i;++j)f[i][j]=0;
  21. }
  22. for(rint i=0;i<=n+1;++i) f[n+1][i]=0;
  23. for(rint i=2;i<=n;++i)for(rint j=1;j+i-1<=n;++j)
  24. for(rint k=max(g[j][j+i-2],j);k<=max(g[j+1][j+i-1],j);++k)
  25. if(f[j][k-1]+f[k+1][i+j-1]+(sum[i+j-1]-sum[j-1])<f[j][i+j-1])
  26. f[j][i+j-1]=f[j][k-1]+f[k+1][i+j-1]+(sum[i+j-1]-sum[j-1]),g[j][i+j-1]=k;
  27. printf("%lld\n",f[1][n]);
  28. }

「题解」数列:exgcd

窝栽了。说真的我看出来$exgcd$了。也写出来了。但是不会用是硬伤。

$exgcd$主要用来解二元一次方程$ax+by=gcd(a,b)$的一组特解。根据这一组特解我们可以推广到$ax+by=c$中。根据裴蜀定理,当且仅当$gcd(a,b)|c$时,方程$ax+by=c$有解。

exgcd的简单证明:

  对于方程$ax+by=gcd(a,b)$,令$a=b,b=a%b$,则有$b*x+a\%b*y=gcd(b,a\%b)$

  又$gcd(a,b)=gcd(b,a\%b)$,所以可得

  $a*x+b*y=b*x+a\%b*b=b*x+(a-a/b*b)*y=a*y+b*(x-a/b*y)$

  得证。

代码实现:

  1. int exgcd(rint a,rint b,rint &x,rint &y)
  2. {
  3. if(!b)
  4. {
  5. x=1;y=0;
  6. return a;
  7. }
  8. rint res=exgcd(b,a%b,x,y);
  9. rint t=x;x=y;y=t-a/b*x;
  10. return res;
  11. }

简要题解:

关于数列这道题,我们需要运用$exgcd$先行解出一组特解。我们最终的目的是使得$abs(x)+abs(y)$最小,我们假设令$a<b$,那么答案一定在$x$取得正数最小值或负数最大值时取得。如果$a>b$,$swap$后再进行解决。

代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define rint register int
  4. using namespace std;
  5. inline void read(rint &a)
  6. {
  7. a=0;rint b=1;register char ch=getchar();
  8. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  9. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  10. a=a*b;return ;
  11. }
  12. int n,A,B,a[100005],dist[200005],fx[4],ans;
  13. bool vis[200005];
  14. int exgcd(rint a,rint b,rint &x,rint &y)
  15. {
  16. if(!b){x=1;y=0;return a;}
  17. rint res=exgcd(b,a%b,x,y);
  18. rint t=x;x=y;y=t-a/b*x;
  19. return res;
  20. }
  21. signed main()
  22. {
  23. // freopen("array.in","r",stdin);
  24. // freopen("1.in","r",stdin);
  25. // freopen("2.out","w",stdout);
  26. read(n),read(A),read(B);
  27. if(A>B)swap(A,B);rint x,y,gcd;
  28. gcd=exgcd(A,B,x,y);
  29. for(rint i=1;i<=n;++i)
  30. {
  31. read(a[i]);
  32. if(a[i]%gcd){puts("-1");return 0;}
  33. rint lx=x*a[i]/gcd,ly=y*a[i]/gcd;
  34. // cout<<"lx:"<<lx<<" ly:"<<ly<<endl;
  35. rint la=A/gcd,lb=B/gcd;
  36. if(lx>0)
  37. {
  38. rint tag=lx/lb,res=0x7fffffffffffffff;
  39. res=min(abs(lx-tag*lb)+abs(ly+tag*la),res);
  40. res=min(abs(lx-(tag+1)*lb)+abs(ly+(tag+1)*la),res);
  41. res=min(abs(lx-(tag-1)*lb)+abs(ly+(tag-1)*la),res);
  42. ans+=res;
  43. }
  44. else
  45. {
  46. rint tag=(-lx)/lb,res=0x7fffffffffffffff;
  47. res=min(abs(lx+tag*lb)+abs(ly-tag*la),res);
  48. res=min(abs(lx+(tag+1)*lb)+abs(ly-(tag+1)*la),res);
  49. res=min(abs(lx+(tag-1)*lb)+abs(ly-(tag-1)*la),res);
  50. ans+=res;
  51. }
  52. }
  53. printf("%lld\n",ans);
  54. }

「题解」最小距离:多源最短路

说实话,从来没有接触过多源最短路。(或者是接触过我忘了??)

简要题解:

spfa最开始将所有源点都塞进队列,跑的时候记录一下每一个节点是被哪个源点更新的就完了。

代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define rint register int
  4. using namespace std;
  5. const int N=200005,M=400005,inf=0x3f3f3f3f3f3f3f3f;
  6. inline void read(rint &a)
  7. {
  8. a=0;rint b=1;register char ch=getchar();
  9. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  10. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  11. a=a*b;return ;
  12. }
  13. int n,m,p,v[M],w[M],nxt[M],first[N],tot;
  14. int id[N],rk[N],ans[N],dist[N],gx[N],st[N],en[N],wi[N];
  15. bool vis[N];
  16. queue <int> q;
  17. inline void build_line(int uu,int vv,int ww)
  18. {
  19. v[++tot]=vv,w[tot]=ww;
  20. nxt[tot]=first[uu],first[uu]=tot;
  21. }
  22. inline void spfa()
  23. {
  24. for(rint i=1;i<=n;++i)
  25. dist[i]=inf,vis[i]=0;
  26. for(rint i=1;i<=p;++i)
  27. gx[id[i]]=i,q.push(id[i]),dist[id[i]]=0;
  28. while(!q.empty())
  29. {
  30. int x=q.front();q.pop();
  31. for(rint i=first[x];i;i=nxt[i])
  32. {
  33. int y=v[i];
  34. if(dist[x]+w[i]<dist[y])
  35. {
  36. dist[y]=w[i]+dist[x],gx[y]=gx[x];
  37. if(!vis[y])vis[y]=1,q.push(y);
  38. }
  39. }
  40. vis[x]=0;
  41. }
  42. return ;
  43. }
  44. signed main()
  45. {
  46. // freopen("distance.in","r",stdin);
  47. read(n),read(m),read(p);
  48. for(rint i=1;i<=p;++i)
  49. read(id[i]),rk[id[i]]=i,ans[i]=inf;
  50. for(rint i=1,ST,EN,WE;i<=m;++i)
  51. {
  52. read(ST),read(EN),read(WE);st[i]=ST,en[i]=EN,wi[i]=WE;
  53. build_line(ST,EN,WE),build_line(EN,ST,WE);
  54. }
  55. spfa();
  56. // for(rint i=1;i<=n;++i)
  57. // cout<<dist[i]<<' '<<gx[i]<<endl;
  58. // cout<<"----------------------"<<endl;
  59. for(rint i=1;i<=m;++i)
  60. {
  61. if(gx[st[i]]!=gx[en[i]])
  62. {
  63. int res=dist[st[i]]+dist[en[i]]+wi[i];
  64. // cout<<i<<' '<<st[i]<<' '<<en[i]<<' '<<res<<endl;
  65. ans[gx[st[i]]]=min(ans[gx[st[i]]],res);
  66. ans[gx[en[i]]]=min(ans[gx[en[i]]],res);
  67. }
  68. }
  69. for(rint i=1;i<=p;++i)
  70. printf("%lld ",ans[i]);puts("");
  71. return 0;
  72. }
  73. /*
  74. 5 6 3
  75. 2 4 5
  76. 1 2 4
  77. 1 3 1
  78. 1 4 1
  79. 1 5 4
  80. 2 3 1
  81. 3 4 3
  82. */

「题解」数对:线段树优化dp

简要题解:

对于随机排部求最优解,考虑最优排部。

如果$a_i<b_j$并且$b_i<a_j$,则此时一定是$i$在$j$前更优。

(因为产生贡献当且仅当$a_i \leq b_j$,上述情况$i$在前可以产生贡献,$j$在前不能产生贡献。)

所以按照$a+b$排序后就是队长快跑的原题了。

之前有一个错解想法,具体是说按照$a_i$的大小建一棵树状数组,按$b_i$查询,按$a_i$修改。

然而后来证伪了。

如上图,我们会用$A$区域的值去更新$i$,此时$a_j$的值被更新到了$a_i$身上。

然后会用$B$区域的值去更新$k$,此时会用$a_j$的值去更新$k$。

等于说我们间接使用$a_j$去更新了$b_k$,而这样的更新是不合法的!

所以在更新的过程中需要分两种情况。对于小于$a_i$的部分,直接取出最大值更新$a_i$单点即可。对于$a_i$和$b_i$之间的部分,我们需要用$i$的贡献去更新他们。线段树实现查询区间最大值、区间加、单点修改即可。

$debug$的时候出了点小问题,线段树下传的节点编号参数我一直喜欢写$k$,结构体内部维护的权值我也喜欢写$k$。本来嘛,因为命名空间不同不会出锅。我也觉得这没啥事。然而这次出锅了。我在$pushdown$中写了这样一句话:$t[k<<1|1],k+=lin$,中间的点写成了逗号。由于传进去的参也是$k$,所以编译没有报错。然后我就死了。所以以后还是要尽量改掉这个写法,传个$x$吧。

代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define rint register int
  4. using namespace std;
  5. inline void read(rint &a)
  6. {
  7. a=0;rint b=1;register char ch=getchar();
  8. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  9. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  10. a=a*b;return ;
  11. }
  12. int n,lsh[200005],cnt,tot;
  13. struct node{int k,lz;}t[1000006];
  14. struct node2{int a,b,w;}p[100005];
  15. inline bool cmp(node2 A,node2 B){return A.a+A.b<B.a+B.b;}
  16. inline void pushdown(int k)
  17. {
  18. if(!t[k].lz)return ;
  19. int lin=t[k].lz;t[k].lz=0;
  20. t[k<<1].k+=lin,t[k<<1].lz+=lin;
  21. t[k<<1|1].k+=lin,t[k<<1|1].lz+=lin;
  22. return;
  23. }
  24. inline void update(int k){t[k].k=max(t[k<<1].k,t[k<<1|1].k);}
  25. inline void add(int k,int l,int r,int L,int R,int dat)
  26. {
  27. if(L<=l&&r<=R)
  28. {
  29. t[k].k+=dat;
  30. t[k].lz+=dat;
  31. return ;
  32. }
  33. pushdown(k);int mid=(l+r)>>1;
  34. if(L<=mid)add(k<<1,l,mid,L,R,dat);
  35. if(R>mid)add(k<<1|1,mid+1,r,L,R,dat);
  36. update(k);return ;
  37. }
  38. inline void change(int k,int l,int r,int p,int dat)
  39. {
  40. if(l==r)
  41. {
  42. t[k].k=max(t[k].k,dat);
  43. return ;
  44. }
  45. pushdown(k);int mid=(l+r)>>1;
  46. if(p<=mid)change(k<<1,l,mid,p,dat);
  47. else change(k<<1|1,mid+1,r,p,dat);
  48. update(k);return ;
  49. }
  50. inline int query(int k,int l,int r,int L,int R)
  51. {
  52. if(L>R)return 0;
  53. if(L<=l&&r<=R)return t[k].k;
  54. pushdown(k);int mid=(l+r)>>1,res=0;
  55. if(L<=mid)res=max(query(k<<1,l,mid,L,R),res);
  56. if(R>mid)res=max(query(k<<1|1,mid+1,r,L,R),res);
  57. update(k);
  58. return res;
  59. }
  60. signed main()
  61. {
  62. read(n);
  63. for(rint i=1;i<=n;++i)
  64. {
  65. read(p[i].a),read(p[i].b),read(p[i].w);
  66. lsh[++tot]=p[i].a,lsh[++tot]=p[i].b;
  67. }
  68. sort(lsh+1,lsh+tot+1);
  69. cnt=unique(lsh+1,lsh+tot+1)-lsh-1;
  70. for(rint i=1;i<=n;++i)
  71. {
  72. p[i].a=lower_bound(lsh+1,lsh+cnt+1,p[i].a)-lsh;
  73. p[i].b=lower_bound(lsh+1,lsh+cnt+1,p[i].b)-lsh;
  74. }
  75. sort(p+1,p+n+1,cmp);
  76. for(rint i=1;i<=n;++i)
  77. {
  78. if(p[i].b>p[i].a)
  79. {
  80. int res=query(1,1,cnt,1,p[i].a)+p[i].w;
  81. change(1,1,cnt,p[i].a,res);
  82. add(1,1,cnt,p[i].a+1,p[i].b,p[i].w);
  83. }
  84. else
  85. {
  86. int res=query(1,1,cnt,1,p[i].b)+p[i].w;
  87. change(1,1,cnt,p[i].a,res);
  88. }
  89. }
  90. printf("%lld\n",t[1].k);
  91. return 0;
  92. }

「题解」序列:三维偏序问题

这东西……我就算不能秒掉也不至于盯着发呆无所适从吧……我承认题目把我骗住了。还是实力不行没有看出来。

简要题解:

对$a$和$b$分别求前缀和,问题转化为了保证$a_{l-1} \leq a_r$并且$b_{l-1} \leq b_r$,求$r-l+1$的最大值。

考虑先进行离散化,然后按$suma$进行排序,然后就转化为了二维偏序问题。

顺序扫并将下标按$sumb$加入树状数组中,每次查询当前最小下标即可。

调代码的过程出现了一些小问题。答案减一其实没有必要。注意一下问题的转化:

$\sum\limits_{i=l}^r a_i \geq 0$并且$\sum\limits_{i=l}^r b_i \geq 0$求$r-l+1$的最大值

$ \Leftrightarrow $

$suma_{l-1} \leq suma_r$并且$sumb_{l-1} \leq sumb_r$求$r-l+1$的最大值。

所以我们查出来的下标其实是$l-1$,我们此时求的$id-query()$其实是$r-(l-1)=r-l+1$,已经没有必要额外加一了。

所以我加了个一反而画蛇添足。

代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define rint register int
  4. #define lowbit(A) A&-A
  5. #define inf 0x7fffffffffffffff
  6. using namespace std;
  7. inline void read(rint &a)
  8. {
  9. a=0;rint b=1;register char ch=getchar();
  10. while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
  11. while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
  12. a=a*b;return ;
  13. }
  14. int n,a[500005],b[500005],ans,t[1000005],lsh[1000005],tot,cnt;
  15. struct node{int a,b,id;}sum[500005];
  16. inline bool cmp(node A,node B){return A.a<B.a;}
  17. inline void add(int x,int dat){for(;x<=cnt;x+=lowbit(x))t[x]=min(t[x],dat);return ;}
  18. inline int query(int x){int res=inf;for(;x;x-=lowbit(x))res=min(t[x],res);return res;}
  19. signed main()
  20. {
  21. // freopen("sequence.in","r",stdin);
  22. read(n);memset(t,0x7f,sizeof(t));
  23. for(rint i=1;i<=n;++i)read(a[i]),sum[i].a=sum[i-1].a+a[i],lsh[++tot]=sum[i].a;
  24. sum[0].a=sum[0].b=0,sum[0].id=0;lsh[++tot]=0;
  25. for(rint i=1;i<=n;++i)read(b[i]),sum[i].b=sum[i-1].b+b[i],lsh[++tot]=sum[i].b,sum[i].id=i;
  26. sort(lsh+1,lsh+tot+1);cnt=unique(lsh+1,lsh+tot+1)-lsh-1;
  27. for(rint i=0;i<=n;++i)sum[i].a=lower_bound(lsh+1,lsh+cnt+1,sum[i].a)-lsh;
  28. for(rint i=0;i<=n;++i)sum[i].b=lower_bound(lsh+1,lsh+cnt+1,sum[i].b)-lsh;
  29. sort(sum,sum+n+1,cmp);
  30. for(rint i=0;i<=n;++i)ans=max(ans,sum[i].id-query(sum[i].b)+1),add(sum[i].b,sum[i].id);
  31. printf("%lld\n",ans-1);
  32. return 0;
  33. }

CSP-S考前各种idea题解乱堆的更多相关文章

  1. 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)

    洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...

  2. NOI前各种Idea总结以及各种文本乱堆

    转载请注明原文地址:https://www.cnblogs.com/LadyLex/p/9227267.html 不过这篇的确没什么*用了转转吧 2018-6-24 关于一类延迟标记(来自UR14 思 ...

  3. [题解](堆)luogu_P1631序列合并

    思路来自题解 作者: Red_w1nE 更新时间: 2016-11-13 20:46 在Ta的博客查看  72 最近有点忙 没时间贴代码了== [分析] 首先,把A和B两个序列分别从小到大排序,变成两 ...

  4. 「题解」NOIP模拟测试题解乱写II(36)

    毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...

  5. 「题解」NOIP模拟测试题解乱写I(29-31)

    NOIP模拟29(B) T1爬山 简单题,赛时找到了$O(1)$查询的规律于是切了. 从倍增LCA那里借鉴了一点东西:先将a.b抬到同一高度,然后再一起往上爬.所用的步数$×2$就是了. 抬升到同一高 ...

  6. 译文---C#堆VS栈(Part One)

    前言 本文主要是讲解C#语言在内存中堆.栈的使用情况,使读者能更好的理解值类型.引用类型以及线程栈.托管堆. 首先感谢原文作者:Matthew Cochran 为我们带来了一篇非常好的文章,并配以大量 ...

  7. 扫描线+堆 codevs 2995 楼房

    2995 楼房  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 地平线(x轴)上有n个矩(lou)形(fan ...

  8. Bzoj 2006: [NOI2010]超级钢琴 堆,ST表

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2222  Solved: 1082[Submit][Statu ...

  9. 堆VS栈

    c#堆VS栈(Part One) 前言 本文主要是讲解C#语言在内存中堆.栈的使用情况,使读者能更好的理解值类型.引用类型以及线程栈.托管堆. 首先感谢原文作者:Matthew Cochran 为我们 ...

随机推荐

  1. Delphi UTF编码 UTF8Encode、UTF8Decode、URLEncode、URLDecode

    一.URL简介    URL是网页的地址,比如 http://www.cnblogs.com.Web 浏览器通过 URL 从 web 服务器请求页面.    由于URL字符串常常会包含非ASCII字符 ...

  2. JavaScript面向对象小抄集

    前言 本文旨在记录JavaScript中面向对象的基础知识 搞明白JavaScript中的面向对象 一切都是对象 JavaScript中,除了基本类型外,其它类型都是对象类型 所谓对象就是若干属性的集 ...

  3. I2C自编设备驱动设计

    一.自编设备驱动模型 at24.c: static int __init at24_init(void) { io_limit = rounddown_pow_of_two(io_limit); re ...

  4. PCB一些设置记录

    开始时设置原点,编辑>>原点>>设置 画PCB时,导入后,根据各个模块放好位置 设计>>类>>添加电源类 设计>>规则>>Cle ...

  5. hdu1059&poj1014 Dividing (dp,多重背包的二分优化)

    Problem Description Marsha and Bill own a collection of marbles. They want to split the collection a ...

  6. PHP基础知识总结(二) 数据类型、数组、变量和运算符

    一.PHP是服务器端的脚本语言.在服务器端解析完成后,向前端浏览器发送html. PHP文件的部署位置在:xampp\htdocs文件夹下,当然这个位置可以修改.二.PHP基本语法 1.文件后缀名是p ...

  7. leetcode中的一些二分搜索树

    235(最近公共祖先) /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left ...

  8. 爬取猎聘大数据岗位相关信息--Python

    猎聘网站搜索大数据关键字,只能显示100页,爬取这一百页的相关信息,以便做分析. __author__ = 'Fred Zhao' import requests from bs4 import Be ...

  9. HTML-参考手册: 画布

    ylbtech-HTML-参考手册: 画布 1.返回顶部 1. HTML5 <canvas> 参考手册 描述 HTML5 <canvas> 标签用于绘制图像(通过脚本,通常是 ...

  10. (12)C++ 继承

    1继承语法 class Base { public: void print() { cout << "Base" << endl; } }; class S ...