Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstring>
- #include <algorithm>
- #include <iostream>
- using namespace std;
- int tree[4000000];
- inline void update(int node,int i,int j,int pos) {
- if(pos<i || pos>j) return;
- if(i==j) {
- tree[node]++;
- return;
- }
- update(node<<1,i,(i+j)>>1,pos);
- update((node<<1)+1,((i+j)>>1)+1,j,pos );
- tree[node]=tree[node<<1]+tree[(node<<1)+1];
- }
- inline int query(int node,int x,int y,int i,int j) {
- if(j<x || i>y)
- return 0;
- if(x>=i && y<=j)
- return tree[node];
- return query(node<<1,x,(x+y)>>1,i,j)+query((node<<1)+1,((x+y)>>1)+1,y,i,j);
- }
- struct my_event
- {
- bool type;
- int pos;
- int val;
- int a,b;
- // int c;
- } S[200001];
- //type: 0->numberEvent , 1->queryEvent
- bool operator < (const my_event &X,const my_event &Y)
- {
- if(X.type==Y.type)
- return X.val>Y.val;
- if(X.type == 0 && Y.type == 1) {
- return X.val >= Y.val;
- }
- if(X.type == 1 && Y.type == 0) {
- return X.val > Y.val;
- }
- return false;
- }
- int result[100001];
- int n;
- int arr[100001];
- bool solved[100001];
- int startOfGroup[100001];
- int endOfGroup[100001];
- int groupSize[100001];
- void precompute() {
- int leftEnd = -1;
- int counter=1;
- for(int i = 1; i <= n; i++) {
- if(i == 1 || arr[i] != arr[i-1]) {
- leftEnd = i;
- if(i > 1) {
- groupSize[i-1] = counter;
- }
- counter = 0;
- }
- counter++;
- startOfGroup[i] = leftEnd;
- if(i == n) {
- groupSize[n] = counter;
- }
- }
- int rightEnd = -1;
- for(int i = n; i >= 1; i--) {
- if(i == n || arr[i] != arr[i+1]) {
- rightEnd = i;
- }
- endOfGroup[i] = rightEnd;
- }
- }
- int main()
- {
- int t;
- cin >> t;
- while(t--) {
- memset(tree,0,sizeof(tree));
- memset(result,0,sizeof(result));
- memset(solved,false,sizeof(solved));
- memset(startOfGroup,0,sizeof(startOfGroup));
- memset(endOfGroup,0,sizeof(endOfGroup));
- memset(groupSize,0,sizeof(groupSize));
- int events=0;
- int i,c,q;
- int a,b;
- cin >> n >> q;
- for(int i = 1; i <= n; i++) {
- cin >> arr[i];
- }
- precompute();
- for(i=1;i<=n;i++) {
- if(groupSize[i] > 0) {
- S[events].pos=i;
- S[events].val=groupSize[i];
- S[events].type=0;
- events++;
- }
- }
- for(i=0;i<q;i++) {
- cin >> a >> b >> c;
- S[events].type=1;
- S[events].a=a;
- S[events].b=b;
- S[events].pos=i;
- S[events].val=c;
- if(startOfGroup[a] == startOfGroup[b] && endOfGroup[a] == endOfGroup[b]) { //one interval
- solved[i] = true;
- result[i] += (b-a+1 >= c ? 1 : 0);
- }
- else
- if(endOfGroup[a]+1 == startOfGroup[b]) { //two intervals
- solved[i] = true;
- int l = a;
- int r = endOfGroup[a];
- result[i] += (r-l+1 >= c ? 1 : 0);
- l = startOfGroup[b];
- r = b;
- result[i] += (r-l+1 >= c ? 1 : 0);
- } else { //3+ intervals
- solved[i] = false;
- int l = a;
- int r = endOfGroup[a];
- result[i] += (r-l+1 >= c ? 1 : 0);
- l = startOfGroup[b];
- r = b;
- result[i] += (r-l+1 >= c ? 1 : 0);
- S[events].a = endOfGroup[a]+1;
- S[events].b = startOfGroup[b]-1;
- }
- events++;
- }
- sort(S,S+events);
- for(i=0;i<events;i++) {
- if(S[i].type==0) {
- update(1,0,n-1,S[i].pos-1);
- }
- else {
- if(!solved[S[i].pos]) {
- result[S[i].pos]+=query(1,0,n-1,S[i].a-1,S[i].b-1);
- }
- }
- }
- for(i=0;i<q;i++) {
- cout << result[i]<<endl;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement