AcWing brush questions (second week) (linked list, monotonic stack, etc...)

1: target sum of array elements

 The first is violence:

The violent method is to traverse the two arrays, if the sum is x, then output the i and j

 Then introduces the double pointer arithmetic

#include<iostream>
using namespace std;
const int N=100010;
int a[N],b[N],n,m,x;

int main(void)
{
    scanf("%d %d %d",&n,&m,&x);
    for(int i=0;i<n;i++) scanf("%d",&a[i]);
    for(int i=0;i<m;i++) scanf("%d",&b[i]);
    
    for(int i=0,j=m-1;i<n;i++)
    {
        while(a[i]+b[j]>x) j--;
        if(a[i]+b[j]==x)
        {
            printf("%d %d\n",i,j);
        }
    }
    return 0;
}

 You can also use binary search to solve the problem: traverse the a array in turn, and then use the current value of the a array to reverse the value that meets the conditions, and then check in the b array to see if it can be found

#include<iostream>
using namespace std;
const int N=100010;
int a[N],b[N],n,m,x;

int main(void)
{
    scanf("%d %d %d",&n,&m,&x);
    for(int i=0;i<n;i++) scanf("%d",&a[i]);
    for(int i=0;i<m;i++) scanf("%d",&b[i]);
    
    for(int i=0;i<n;i++)
    {
        int y=x-a[i];
        int l=0,r=m-1;
        while(l<=r)
        {
            int mid=l+r>>1;
            if(b[mid]==y)
            {
                printf("%d %d",i,mid);
                return 0;
            }else if(b[mid]<y)
            {
                l=mid+1;
            }else
            {
                r=mid-1;
            }
        }
    }
    return 0;
}

2. Interval and

 

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int N = 1000010;
typedef pair<int, int>PII;
vector<PII>query, add;//询问区间还有需要增加的
vector<int>alls;
int a[N], s[N];//s[N]为前缀和
int n, m, l, r, c, x;

int find(int x)
{
	int l = 0, r = alls.size() - 1;
	while (l < r)
	{
		int mid = l + r >> 1;
		if (alls[mid] >= x)
		{
			r = mid;
		}
		else
		{
			l = mid + 1;
		}
	}
	return l + 1;
}

int main(void)
{
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++)
	{
		scanf("%d %d", &x, &c);
		add.push_back({ x,c });
		alls.push_back(x);
	}
	for (int i = 0; i < m; i++)
	{
		scanf("%d %d", &l, &r);
		query.push_back({ l,r });
		alls.push_back(l);
		alls.push_back(r);
	}
	//对所有的区间进行排序,然后进行去重,离散化
	sort(alls.begin(), alls.end());
	alls.erase(unique(alls.begin(), alls.end()), alls.end());
	for (auto tmp : add)
	{
		int x = find(tmp.first);
		a[x] += tmp.second;
	}
	//求前缀和
	for (int i = 1; i <= alls.size(); i++)
	{
		s[i] = s[i - 1] + a[i];
	}
	//求区间和
	for (auto tmp : query)
	{
		int l = find(tmp.first), r = find(tmp.second);
		printf("%d\n", s[r] - s[l - 1]);
	}
	return 0;
}

 3. Double linked list

 First of all, we agree that the head of the linked list is 0, and the tail is 1. Here we are talking about subscripts.

So first initialize the linked list

Then insert operation:

 Deleting is as simple as:

	r[l[k]] = r[k];
	l[r[k]] = l[k];
#include<iostream>
using namespace std;
int m;
const int N = 100010;
int e[N], r[N], l[N], idx;

void init()
{
	r[0] = 1;
	l[1] = 0;
	idx = 2;
}

void add(int k, int x)
{
	e[idx] = x;
	r[idx] = r[k];
	l[idx] = k;
	l[r[k]] = idx;
	r[k] = idx;
	idx++;
}

void move(int k)
{
	r[l[k]] = r[k];
	l[r[k]] = l[k];
}

int main(void)
{
	cin >> m;
	init();
	while (m--)
	{
		string op;
		cin >> op;
		int k, x;
		if (op == "R")
		{
			cin >> x;
			add(l[1], x);
		}
		else if (op == "L")
		{
			cin >> x;
			add(0, x);
		}
		else if (op == "D")
		{
			cin >> k;
			move(k + 1);
		}
		else if (op == "IL")
		{
			cin >> k >> x;
			add(l[k + 1], x);
		}
		else {
			cin >> k >> x;
			add(k + 1, x);
		}
	}
	for (int i = r[0]; i != 1; i = r[i])
	{
		cout << e[i] << " ";
	}
	return 0;
}

4: Monotonic stack

Violent solution: Traverse forward from the current position one by one to see if there is a number that satisfies the condition, output if there is, and output -1 if not

When we have traversed the previous numbers, we can use known information to reduce the number of traversals

Ideas:

#include<iostream>
using namespace std;
const int N=100010;
int stk[N],m,x,tt;

int main(void)
{
    scanf("%d",&m);
    while(m--)
    {
        scanf("%d",&x);
        while(stk[tt]>=x&&tt)
        {
            tt--;
        }
        if(tt) printf("%d ",stk[tt]);
        else printf("-1 ");
        stk[++tt]=x;
    }
    return 0;
}

 

Guess you like

Origin blog.csdn.net/AkieMo/article/details/128438359