Luo Gu solution to a problem [P4198] building reconstruction

First clear the problem, the slope of a complete circuit of the building K = H / X, the problem is to ask how many buildings of K K is bigger than all the previous building.

This problem tree cover tree course, but very troublesome, the residue think the most simple is the block ......

Into the N T building blocks, each constant maintenance visual sequences within the building block, such as the height of a building block, respectively (314,267) then visible in this sequence is the building block (34 67) (Note that does not interfere with the different blocks, as in the first sequence of visual block (346), the second block may be a sequence (578))

For each modification, we only need to violence buildings visible within each block maintains the sequence on the line, O (N / T)

For each inquiry, we need only look at a block by block, the maximum value kmax constant maintenance so far in the visual sequence of K (K value of the building is not in a certain sequence is not visual), then for each query when the block, the sequence can be found the first half of a visible location is greater than kmax, if not all of the buildings of this block is visible, if present, the sequence of buildings visible in this block after this position can see, then update the answer and kmax, continue to do next

Note: After all, time is tight, so the constant is written as a small point, two points and write their own max function or better, or will burst RP ...

 1 #include<cstdio>
 2 #include<cmath>
 3 const int maxn=100005,sqrn=350;
 4 int h[maxn],v[sqrn][sqrn],c[sqrn],l[sqrn],r[sqrn],bel[maxn],n,m,block,cnt,x,y,ch;
 5 void read(int&x) {
 6     x=0,ch=getchar();
 7     while(ch>'9'||ch<'0')ch=getchar();
 8     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
 9 }
10 bool vis(int x,int y) {
11     return (long long)h[x]*y<(long long)h[y]*x;
12 }
13 int bfind(int*a,int l,int r,int mx) {
14     if(!mx)return l;
15     if(!vis(mx,a[r]))return 0;
16     int m=0,ans=0;
17     while(l<=r) {
18         m=(l+r)>>1;
19         if(vis(mx,a[m]))ans=m,r=m-1;
20         else l=m+1;
21     }
22     return ans;
23 }
24 void build(int x) {
25     c[x]=0;
26     int lst=0;
27     for(register int i=l[x]; i<=r[x]; ++i)if(h[i])if(!lst||vis(lst,i))lst=v[x][++c[x]]=i;
28 }
29 int query() {
30     int tot=0,mx=0,pos;
31     for(register int i=1; i<=cnt; ++i)if(c[i]) {
32             pos=bfind(v[i],1,c[i],mx);;
33             if(pos)tot+=c[i]-pos+1,mx=v[i][c[i]];
34         }
35     return tot;
36 }
37 int main() {
38     read(n),read(m);
39     block=sqrt(n);
40     cnt=n/block;
41     if(n%block)++cnt;
42     for(register int i=1; i<=n; ++i)bel[i]=(i-1)/block+1;
43     for(register int i=1; i<=cnt; ++i)l[i]=(i-1)*block+1,r[i]=i*block;
44     r[cnt]=n;
45     for(register int i=1; i<=m; ++i) {
46         read(x),read(y);
47         h[x]=y;
48         build(bel[x]);
49         printf("%d\n",query());
50     }
51     return 0;
52 }
Garbage chicken neck code

 

Guess you like

Origin www.cnblogs.com/Xchu/p/11265867.html