Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstring>
- #include <cstdio>
- #include <cstdlib>
- #include <algorithm>
- #include <iostream>
- #include <fstream>
- using namespace std;
- int tree[30000000];
- inline void update(int node,int i,int j,int pos)
- {
- if(pos<i || pos>j) return;
- if(i==j) // && pos==i
- {
- 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[23000001];
- //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;
- //return (X.type>Y.type && X.val<Y.val) || X.val>Y.val;
- }
- int result[20000000];
- int n;
- int arr[20000000];
- bool solved[20000000];
- int leftPoint[20000000];
- int rightPoint[20000000];
- int groupSize[20000000];
- 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++;
- leftPoint[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;
- }
- rightPoint[i] = rightEnd;
- }
- // for(int i = 1; i <= n; i++) {
- // cout << groupSize[i] << " ";
- // }
- // cout << endl;
- }
- int main()
- {
- int t;
- // ifstream cin("input.txt");
- cin >> t;
- while(t--) {
- memset(tree,0,sizeof(tree));
- memset(result,0,sizeof(result));
- memset(solved,false,sizeof(solved));
- memset(leftPoint,0,sizeof(leftPoint));
- memset(rightPoint,0,sizeof(rightPoint));
- 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(leftPoint[a] == leftPoint[b] && rightPoint[a] == rightPoint[b]) { //one interval
- solved[i] = true;
- result[i] += (b-a+1 >= c ? 1 : 0);
- }
- else
- if(rightPoint[a]+1 == leftPoint[b]) { //two intervals
- solved[i] = true;
- int l = a;
- int r = rightPoint[a];
- result[i] += (r-l+1 >= c ? 1 : 0);
- l = leftPoint[b];
- r = b;
- result[i] += (r-l+1 >= c ? 1 : 0);
- } else { //3+ intervals
- solved[i] = false;
- int l = a;
- int r = rightPoint[a];
- result[i] += (r-l+1 >= c ? 1 : 0);
- l = leftPoint[b];
- r = b;
- result[i] += (r-l+1 >= c ? 1 : 0);
- S[events].a = rightPoint[a]+1;
- S[events].b = leftPoint[b]-1;
- }
- // cout << S[events].a << " " << S[events].b << endl;
- 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);
- }
- }
- // cout << S[i].type << ": ";
- // if(S[i].type == 0) {
- // cout << S[i].val << endl;
- // } else {
- // cout << S[i].a << " " << S[i].b << " " << S[i].val<< endl;
- // }
- }
- for(i=0;i<q;i++) {
- cout << result[i]<<endl;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement