1. 程式人生 > 其它 >Red Hat Enterprise Linux 8系統學習(七)

Red Hat Enterprise Linux 8系統學習(七)

技術標籤:訓練題解ACM-Icpc演算法

A題,題意比較簡單問是否能夠讓所有的數,小於k,;操作無限次,每次操作就是找兩個數加起來替換這一個。所以只需要判斷最小的兩個加起來是不是比k小或者全部都是小於k的。

在這裡插入程式碼片

B題

  • 找兩個字串的最小公倍數字符串
  • 思路
  • 程式碼
while(t--){
      string a, b;
      cin>>a>>b;
      //shorter string must be prefix of bigger one
      //take lcm of their lengths, this is length of new string
int len = (a.size() * b.size()) / (__gcd(a.size(), b.size())); string res = ""; while(len){ res += b; len -= b.size(); } bool bad = 0; forn(i, res.size(), 1){ if(a[i%a.size()] != res[i]){ bad = 1; break
; } } if(bad){ cout<<-1<<endl; } else { cout<<res<<endl; } }

D題

題目連結
題意:
一開始陣列全是0
然後給一個操作字串±,
+代表+1,-代表-1;
問你忽略某個區間的操作後,還有幾種數字。
例如樣例1
在這裡插入圖片描述
在這裡插入圖片描述

忽略1、8區間的;那麼只有0了,所以答案為1
忽略2,8區間,序列就變成了-1,0000000,所以答案為2
忽略2,5區間,序列就變成了-1,0,0,0,0,-2,-3,-2;所以答案為4,

忽略1,1 區間,序列就變成了1,0,-1,0,-1,-2,-1;所以答案為4;

  • 思路
  • 在這裡插入圖片描述
要減去中間的。
這題就是把加號抽象成1,減號抽象成-1,記做陣列a(1~n標號),然後求出陣列a的字首和陣列為s。(s[0] = 0)
然後對於區間[l,r],答案就是然後分別在字首和陣列s上對區間[0,l-1],[r+1,n]查詢最小值,最大值,分別記為minl1,maxl1,minl2,maxl2。那麼此時的答案就是 max(maxl1,maxl2)-min(minl1,minl2)+1。
  • 程式碼
//Dlove's template
#include <iostream>
#include <algorithm>
#include <string>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>

#define R register
#define ll long long
#define ull unsigned long long
#define db double
#define ld long double
#define Ls root << 1
#define Rs Ls | 1
#define sqr(_x) ((_x) * (_x))
#define Cmax(_a, _b) ((_a) < (_b) ? (_a) = (_b), 1 : 0)
#define Cmin(_a, _b) ((_a) > (_b) ? (_a) = (_b), 1 : 0)
#define Max(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define Min(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define Abs(_x) (_x < 0 ? (-(_x)) : (_x))

using namespace std;

//#define getchar() (_S == _T && (_T = (_S =_B) + fread(_B, 1, 1 << 15, stdin), _S == _T) ? 0 : *_S++)
//char _B[1 << 15], *_S = _B, *_T = _B;

inline int read()
{
 R int a = 0, b = 1; R char c = getchar();
 for(; c < '0' || c > '9'; c = getchar()) (c == '-') ? b = -1 : 0;
 for(; c >= '0' && c <= '9'; c = getchar()) a = (a << 1) + (a << 3) + c - '0';
 return a * b;
}
inline ll lread()
{
 R ll a = 0, b = 1; R char c = getchar();
 for(; c < '0' || c > '9'; c = getchar()) (c == '-') ? b = -1 : 0;
 for(; c >= '0' && c <= '9'; c = getchar()) a = (a << 1) + (a << 3) + c - '0';
 return a * b;
}

const int maxn = 200010;
int a[maxn];
int s[maxn];
int c[maxn];
int d[maxn];

ll lowbit(ll x)
{
    return x&(-x);
}

void change(int r)
{
    c[r]=s[r];
    for(int i=1;i<lowbit(r);i<<=1){
        c[r]=max(c[r],c[r-i]);
    }
}

int getmax(int l,int r)
{
    int ret=s[r];
    while(l<=r){
        ret=max(ret,s[r]);
        for(--r;r-l>=lowbit(r);r-=lowbit(r)){
            ret=max(ret,c[r]);
        }
    }
    return ret;
}

void change2(int r)
{
    d[r]=s[r];
    for(int i=1;i<lowbit(r);i<<=1){
        d[r]=min(d[r],d[r-i]);
    }
}

int getmin(int l,int r)
{
    int ret=s[r];
    while(l<=r){
        ret=min(ret,s[r]);
        for(--r;r-l>=lowbit(r);r-=lowbit(r)){
            ret=min(ret,d[r]);
        }
    }
    return ret;
}

int main()
{
	int t;
	cin >> t;
	while(t--){
		memset(c,0,sizeof(c));
		memset(d,0,sizeof(d));
		int n,m;
		cin >> n >> m;
		string ss;
		cin >> ss;
		for(int i = 0;i<n;i++){
			if(ss[i] == '+') a[i+1] = 1;
			else a[i+1] = -1;
		}
		s[0] = 0;
		for(int i = 1;i <= n;i++){
			s[i] = s[i-1]+a[i];
			change(i);
			change2(i);
		}
	    int l,r;
		for(int i = 0;i<m;i++){
			cin >> l >> r;
			int x = s[r]-s[l-1];
			int maxl = max(max(getmax(1,l-1),0),getmax(r+1,n)-x);
			int minl = min(min(getmin(1,l-1),0),getmin(r+1,n)-x);
			cout << maxl-minl+1 << endl; 
		}
	}
// printf("%d\n", read() + read());
 return 0;
}