CF 813E Army Creation block and chairman tree

Posted by Jason Batten on Fri, 18 Oct 2019 22:28:39 +0200

I. partitioned

The core is to find out what to maintain. Imagine that in a column of numbers, we take out the same group. We need to take no more than k numbers within a given range. If the violence is judged from left to right and the number is recorded, it is not realistic. Then we will open an array to record whether the number of positions + K in this group will exceed the number of this group, but the key to statistics later is not "from left to right". If the number + k is still in the range, we will not make a record, because there will be many restrictions, and the middle block is not easy to ask, so it is easy to make mistakes (but maybe it can be written). We can change our thinking and focus on the ones that are larger than the boundary after + K, which means that we won't take more than k, so ans + +; then we can divide them into blocks, one by one on both sides, and use dichotomy in the middle to find the ones that are larger than the boundary, so we need sort preprocessing.

//I'm the only one who can understand the untidy explanation.~~

 1 #include<bits/stdc++.h>
 2 #include<iostream>
 3 #include<stack>
 4 #include<algorithm>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<cstring>
 8 #define mem(a) memset(a,0,sizeof(a))
 9 #define ll long long
10 #define mp make_pair
11 #define pb push_back
12 #define inf 0x3f3f3f3f
13 using namespace std;
14 const int N=1e5+5;
15 int n,blo,num,belong[N],l[N],r[N],d[N],a[N],b[N],mx=0,k;
16 int nx[N];
17 vector<int>cnt[N];
18 void build()
19 {
20     blo=sqrt(n);
21     num=n/blo;
22     if(n%blo) num++;
23     for(int i=1;i<=n;i++)
24      {
25          belong[i]=((i-1)/blo)+1;
26          b[i]=nx[i];
27      }
28     for(int i=1;i<=num;i++)
29     {
30         l[i]=(i-1)*blo+1;
31         r[i]=i*blo;
32     }
33     r[num]=n;
34     for(int i=1;i<=num;i++)
35         sort(b+l[i],b+r[i]+1);
36 }
37 int query(int x,int y)
38 {
39    int ans=0;
40    for(int i=x;i<=min(r[belong[x]],y);i++)
41           if(nx[i]>y) ans++;
42    if(belong[x]!=belong[y])
43    {
44        for(int i=l[belong[y]];i<=y;i++)
45           if(nx[i]>y) ans++;
46        for(int i=belong[x]+1;i<=belong[y]-1;i++)
47        {
48            int j=b+r[i]+1-upper_bound(b+l[i],b+r[i]+1,y);
49            ans+=j;
50        }
51    }
52     return ans;
53 }
54 int main()
55 {
56      scanf("%d%d",&n,&k);
57      for(int i=1;i<=n;i++)
58      {
59           scanf("%d\n",&a[i]);
60           mx=max(mx,a[i]);
61      }
62      for(int i=1;i<=n;i++)
63         cnt[a[i]].pb(i);
64      for(int i=1;i<N;i++)
65      {
66          for(int j=0;j<cnt[i].size();j++)
67          {
68              if(j+k>=cnt[i].size())
69                 nx[cnt[i][j]]=N;
70              else
71                 nx[cnt[i][j]]=cnt[i][j+k];
72          }
73      }
74      build();
75      int last=0,m;
76      scanf("%d",&m);
77      while(m--)
78      {
79          int ans=0;
80          int L,R;
81          scanf("%d%d",&L,&R);
82          L=(L+last)%n+1;
83          R=(R+last)%n+1;
84          if(L>R)swap(L,R);
85          if(R-L+1<=k) ans=R-L+1;
86          else  ans=query(L,R);
87          printf("%d\n",ans);
88          last=ans;
89      }
90      build();
91 
92 }
<( ̄︶ ̄)↗[GO!]

Topics: PHP