注意:这是一篇十分劣质的博客,只有题目和简单的几句话,慎用。。。。。。。。。。OVO

分块

入门推荐:http://hzwer.com/8053.html

bzoj2957

        这个题有线段树和分块两种做法;

       线段树维护了区间的答案合并的时候维护高度最大值,右区的左子区间进一步讨论对分类讨论;

       分块就对每个块维护一个可看到的上升序列,lower_bound即可;

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define il inline 
 4 #define rg register  
 5 using namespace std;
 6 const int N=100010,M=610;
 7 int n,m,bl[N],u,t[M],len;
 8 double a[N],g[M][M]; 
 9 il int find(int i,double x){
10     int l=1,r=t[i]+1;
11     while(l<r){
12         int mid=(l+r)>>1;
13         if(x<g[i][mid])r=mid;
14         else l=mid+1;
15     }
16     return l;
17 }
18 il void update(int x){
19     int l=(bl[x]-1)*u+1,r=bl[x]*u;
20     t[bl[x]]=0;
21     for(rg int i=l;i<=r;i++)
22     if(g[bl[x]][t[bl[x]]]<a[i])g[bl[x]][++t[bl[x]]]=a[i];
23     double mx=0; int ans=0;
24     for(rg int i=1;i<=len;i++){
25         int p = find(i,mx);
26         ans += t[i]-p+1; 
27         if(mx<g[i][t[i]])mx=g[i][t[i]];
28     }
29     printf("%d\n",ans);
30 }
31 il char gc(){
32     static char *p1,*p2,s[1000000];
33     if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
34     return(p1==p2)?EOF:*p1++; 
35 } 
36 il int rd(){
37     int x=0; char c=gc();
38     while(c<'0'||c>'9')c=gc();
39     while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();
40     return x;
41 }
42 int main(){
43 //    freopen("bzoj2957.in","r",stdin);
44 //    freopen("bzoj2957.out","w",stdout);
45     n=rd(); m=rd();
46     u=550;
47     for(rg int i=1;i<=n;i++)bl[i]=(i-1)/u+1;
48     len=bl[n];
49     for(rg int i=1;i<=n;i++)a[i]=-1;
50     for(rg int i=1,x,y;i<=m;i++){
51         x=rd(),y=rd();
52         a[x]=1.0*y/x;
53         update(x);
54     }
55     return 0;
56 }
bzoj2957

相关文章:

  • 2021-10-08
  • 2021-10-23
  • 2021-10-25
  • 2021-10-02
  • 2022-02-12
  • 2021-10-07
  • 2022-02-23
  • 2022-12-23
猜你喜欢
  • 2021-11-17
  • 2022-01-10
  • 2022-01-26
  • 2021-07-01
  • 2021-10-05
  • 2021-10-14
  • 2021-06-16
相关资源
相似解决方案