Codeforces Round #741 (Div. 2) D2. Two Hundred Twenty One (hard version) prefix and + segmentation model

Posted by paolo on Wed, 22 Dec 2021 19:37:31 +0100

Portal

Meaning:

Give you a length of n n String of n, + + +Represent 1 1 1, − - − representative − 1 -1 − 1, let the rear have q q q queries per query [ l , r ] [l,r] [l,r] interval, take out the number of this interval and set it as a [ 1 , r − l + 1 ] a[1,r-l+1] a[1,r − l+1], calculate a 1 − a 2 + a 3 − . . . = x a_1-a_2+a_3-...=x a1​−a2​+a3​−...= x. Ask how many numbers to delete at least to make x x x is 0 0 0, output the position of the deleted number.

n , q ≤ 3 e 5 n,q\le3e5 n,q≤3e5

Idea:

First, consider the simple version, that is, you do not need to output the deletion location, but only consider how much to delete.

Each time the interval is asked, the parity position symbols are multiplied respectively 1 , − 1 1,-1 1, − 1, it's not difficult to find that we will − 1 , 1 -1,1 − 1,1 has no effect on the reverse, that is, even odd multiplication 1 , − 1 1,-1 1,−1.

Well, since the interval we take out has no effect on the position parity, let's consider dealing with one at the beginning a [ i ] a[i] a[i] represents the second i i The number of i locations, and then maintain a prefix and s u m [ i ] sum[i] sum[i], we can get it now [ l , r ] [l,r] The sum of [l,r] and consider how to calculate the answer.

( 1 ) (1) (1) If the current interval sum is 0 0 0, then the answer is obviously 0 0 0.

( 2 ) (2) (2) If the sum of the current interval is odd, you can find a position. After removing the current position, the sum of the interval is 0 0 0.

( 3 ) (3) (3) If the sum of the current interval is even, then we can l l Delete the position of l, so that the interval sum must become an odd number, and then follow it ( 2 ) (2) (2) Just find a place to remove it.

So if so e a s y easy The easy version can be discussed in the above three ways.

Consider what to do if the output position is required.

about ( 1 ) (1) (1) , direct output 0 0 0 is enough.

about ( 2 ) (2) (2) , because there must be a position, the sum of the removed interval is 0 0 0. What position is considered to be legal? Suppose we remove the position p o s pos pos, so [ l , p o s − 1 ] , [ p o s + 1 , r ] [l,pos-1],[pos+1,r] The sum of [l,pos − 1] and [POS + 1, R] was originally the same, that is s u m [ l , p o s − 1 ] = s u m [ p o s + 1 , r ] sum_{[l,pos-1]}=sum_{[pos+1,r]} sum[l,pos − 1] = sum[pos+1,r], then we remove it p o s pos After the pos bit, the previous values remain unchanged, and the subsequent values are all reversed, that is s u m [ l , p o s − 1 ] = − s u m [ p o s + 1 , r ] sum_{[l,pos-1]}=-sum_{[pos+1,r]} sum[l,pos − 1] = − sum[pos+1,r], that is, we can find such a legal location.

Consider how to find it? Obviously, you can find the two-point position. It's a little cumbersome. Let's consider a better way.

We give everyone s u m [ i ] + s u m [ i − 1 ] sum[i]+sum[i-1] sum[i]+sum[i − 1] open a bucket and save it i i i this position, considering that the current query interval is [ l , r ] [l,r] [l,r]. You then we find s u m [ l − 1 ] + s u m [ r ] sum[l-1]+sum[r] A position in the bucket corresponding to sum[l − 1]+sum[r] x x x. So now there are s u m [ r ] + s u m [ l − 1 ] = s u m [ x ] + s u m [ x + 1 ] sum[r]+sum[l-1]=sum[x]+sum[x+1] sum[r]+sum[l − 1]=sum[x]+sum[x+1], obtained by item transfer s u m [ r ] − s u m [ x + 1 ] = s u m [ x ] − s u m [ l − 1 ] sum[r]-sum[x+1]=sum[x]-sum[l-1] sum[r] − sum[x+1]=sum[x] − sum[l − 1], it is not difficult to find if we will x + 1 x+1 After the position x+1 is removed, the sum of the two intervals is 0 0 0, so we just need to s u m [ i ] + s u m [ i − 1 ] sum[i]+sum[i-1] sum[i]+sum[i − 1] can be divided into two positions in the barrel. Since there must be a solution, there must be such a position.

about ( 3 ) (3) (3) , delete l l l position, change it to an odd number and let it proceed ( 2 ) (2) (2) Just.

// Problem: D1. Two Hundred Twenty One (easy version)
// Contest: Codeforces - Codeforces Round #741 (Div. 2)
// URL: https://codeforces.com/contest/1562/problem/D1
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#include<random>
#include<cassert>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid ((tr[u].l+tr[u].r)>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;

//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;

const int N=2000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;

int n,q;
int a[N],sum[N];
vector<int>v[N];
char s[N];

int get(int l,int r) {
	int now=sum[l]+sum[r]+2*n;
	int pos=lower_bound(v[now].begin(),v[now].end(),l+1)-v[now].begin();
	return v[now][pos];
}

int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);
	
	int _; scanf("%d",&_);
	while(_--) {
		scanf("%d%d%s",&n,&q,s+1);
		for(int i=1;i<=n;i++) {
			if(s[i]=='-') {
				if(i%2==1) sum[i]=sum[i-1]-1;
				else sum[i]=sum[i-1]+1;
			}
			else {
				if(i%2==1) sum[i]=sum[i-1]+1;
				else sum[i]=sum[i-1]-1;
			}
		}
		for(int i=1;i<=n;i++) v[sum[i]+sum[i-1]+2*n].pb(i);
		while(q--) {
			int l,r; scanf("%d%d",&l,&r);
			int now=abs(sum[r]-sum[l-1]);
			if(now==0) puts("0");
			else if((r-l+1)%2==1) {	
				puts("1");
				printf("%d\n",get(l-1,r));
			} else {
				puts("2");
				printf("%d %d\n",l,get(l,r));
			}
		}
		for(int i=1;i<=n;i++) v[sum[i]+sum[i-1]+2*n].clear();
	}



	return 0;
}
/*
1
14 3
+--++---+++---  
1 14
6 12  ---+++- -1 1 -1 -1 1 -1 -1 
3 10

2
1 5
1
12
0


*/









Topics: Algorithm Dynamic Programming