MT码题解

门票

#include<bits/stdc++.h> 

using namespace std;
const int MOD = 1e9 + 7;
const int N = 1e6 + 10;
#define ll long long
ll n,t,a[N],sum[N],ans;
ll q[N];

void merge_sort(int l,int r, ll *a)
{
    if( l>=r)
        return;
    int mid=l+r>>1;
    merge_sort(l,mid,a),merge_sort(mid+1,r,a);
    int i=l,j=mid+1,t=0;
    while(i<=mid &&j<=r)
    {
        if(a[i]<=a[j])
        {
            q[t++]=a[j++];
            ans+=mid-i+1;
            ans%=MOD;
        }else
            q[t++]=a[i++];
    }
    while(i<=mid) q[t++]=a[i++];

    while(j<=r) q[t++]=a[j++];

    for(i=l,j=0;i<=r;i++,j++)
    {
        a[i]=q[j];
    }
}

int main( )
{
    cin>>n;
    cin>>t;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        a[i]-=t;
        sum[i]=sum[i-1]+a[i];
      
    }
    merge_sort(0,n,sum);
    cout<<ans%MOD;
    
    return 0;
}

逆波兰算法

#include<bits/stdc++.h> 
#include<string.h>
using namespace std;

bool isop(char c)
{
    return c == '+' || c == '-' || c == '*' || c == '/';
}

int priority(char op)
{
    if (op == '+' || op == '-')
        return 1;
    if (op == '*' || op == '/')
        return 2;
    if (op == '^')
        return 3;
    return -1;
}

void bolan(string s)
{
    stack<int> st;
    bool change = false;
    for (int i = 0; i < s.length(); i++)
    {
        if (isop(s[i]))
        {
            int r = st.top();
            st.pop();
            int l = st.top();
            st.pop();
            switch (s[i])
            {
            case '+':
                st.push(l + r);
                break;
            case '-':
                st.push(l - r);
                break;
            case '*':
                st.push(l * r);
                break;
            case '/':
                st.push(l / r);
                break;
            }
            change = true;
        }
        else
            {st.push(s[i] - '0');
             change = false;}
        if (change)
        {
            stack<int> temp, temp2;
            temp = st;
            while (!temp.empty())
            {
                temp2.push(temp.top());
                temp.pop();
            }
            while (!temp2.empty())
            {
                cout << temp2.top() << " ";
                temp2.pop();
            }
            for (int j = i + 1; j < s.length(); j++)
                cout << s[j] << " ";
            cout << endl;
        }
    }
}
string toRPN(string s)
{
    stack<char> st;
    stack<char> op;
    for (int i = 0; i < s.size(); i++)
    {
        if (s[i] == '(')
            op.push('(');
        else if (s[i] == ')')
        {
            while (op.top() != '(')
            {
                st.push(op.top());
                op.pop();
            }
            op.pop();
        }
        else if (isop(s[i]))
        {
            while (!op.empty() && priority(op.top()) >= priority(s[i]))
            {
                st.push(op.top());
                op.pop();
            }
            op.push(s[i]);
        }
        else
            st.push(s[i]);
    }
    while (!op.empty())
    {
        st.push(op.top());
        op.pop();
    }
    string ans;
    int len = st.size();
    while (len--)
    {
        ans = st.top() + ans;
        st.pop();
    }
    return ans;
}
int main()
{
    string s;
    cin >> s;
    string s2 = toRPN(s);
    for (int i = 0; i < s2.length(); i++)
        cout << s2[i] << " ";
    cout << endl;
    bolan(s2);
    return 0;
}

新月轩就餐


#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;

vector<int> a[2001];
int originalData[1000010];
int thInA[1000010];
// int loc[2001];
priority_queue<int, vector<int>, greater<int>> pq;

int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cd(originalData[i]);
        thInA[i] = a[originalData[i]].size();
        a[originalData[i]].push_back(i);
    }
    int ans = INT_MAX;
    int ansA, ansB;
    int maxValInQueue = 0;
    for (int i = 1; i <= m; i++) {
        pq.push(a[i][0]);
        maxValInQueue = max(maxValInQueue, a[i][0]);
    }
    while (true) {
        int minValInQueue = pq.top();
        pq.pop();
        if (maxValInQueue - minValInQueue < ans) {
            ans = maxValInQueue - minValInQueue;
            ansA = minValInQueue, ansB = maxValInQueue;
        }
        int removedWhose = originalData[minValInQueue];
        int thOfHim = thInA[minValInQueue];
        thOfHim++;
        if (thOfHim == a[removedWhose].size()) {
            break;
        }
        int newVal = a[removedWhose][thOfHim];
        maxValInQueue = max(maxValInQueue, newVal);
        pq.push(newVal);
    }
    cout << ansA << " " << ansB << endl;
    return 0;
}

植发

#include<bits/stdc++.h> 

using namespace std;
const int N = 1e4 + 7;
struct NODE {
    int x, y;
    int dis;
    bool operator<(const NODE& a)const { return dis < a.dis; }
};
int a1[N], a2[N], n, m, k, l;//a1a2存储了不同的寿命头发多少根
bool used[N][N];
vector<pair<int, int>> s1[N], s2[N];//s1s2存储的是不同距离下有哪些点
priority_queue<NODE> down, up;
int dist(int x1, int y1, int x2, int y2) { return abs(x1 - x2) + abs(y1- y2); }

int main()
{
    cin >> n >> m;
    cin >> k;
    for (int i = 0; i < k; i++)
    {
        int x;
        cin >> x;
        a1[x]++;
    }
    cin >> l;
    for (int i = 0; i < l; i++)
    {
        int x;
        cin >> x;
        a2[x]++;
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            s1[dist(i, j, 0, 0)].push_back({ i,j });
            s2[dist(i, j, 0, m + 1)].push_back({ i,j });
        }
    }
    int flag = 0;
    for (int i = 1; i <= n + m; i++)
    {//遍历每一个距离
        for (int j = 0; j < s1[i].size(); j++)
        {//对于指定的距离,把符合的点
            int x = s1[i][j].first, y = s1[i][j].second;
            int tmp = dist(x, y, 0, m + 1);
            down.push({ x,y,tmp });
        }
        for (int j = 0; j < a1[i]; j++)
        {//来放[0,0]的每一根头发
            if (down.empty())
            {
                flag = 1;
                break;
            }
            int tmpx = down.top().x, tmpy = down.top().y;
            down.pop();
            used[tmpx][tmpy] = 1;
        }
        if (flag == 1)
            break;
    }
    for (int i = 1; i <= n + m; i++)
    {//遍历每一个距离
        for (int j = 0; j < s1[i].size(); j++)
        {//对于指定的距离,把符合的点
            int x = s2[i][j].first, y = s2[i][j].second;
            if (used[x][y] == 1)
                continue;
            NODE tmp;
            tmp.dis = dist(x, y, 0, 0), tmp.x = x, tmp.y = y;
            up.push(tmp);
        }
        for (int j = 0; j < a2[i]; j++)
        {//来放[0,0]的每一根头发
            if (up.empty())
            {
                flag = 1;
                break;
            }
            int tmpx = up.top().x, tmpy = up.top().y;
            up.pop();
            used[tmpx][tmpy] = 1;
        }
        if (flag == 1)
            break;
    }
    if (flag == 0)
    {
        cout << "YES";
    }
    else
    {
        cout << "NO";
    }
   return 0;
 }

第一节离数课后

#include<bits/stdc++.h> 

using namespace std;
const int N = 267;
string s[N]; int cnt, s2[N];
bool is_op(string s) { return s == "or" || s == "and" || s == "not"; }
int priority(string op) {
    if (op == "or")
        return 1;
    if (op == "and")
        return 2;
    if (op == "not")
        return 3;
    return -1;
}
void process_op(stack<string>& st, string op)
{
    string l, r;
    r = st.top();
    st.pop();
    if (!st.empty())
        l = st.top();
    if (op == "not")
    {
        if (r == "true")
            st.push("false");
        else
            st.push("true");
    }
    if (op == "and")
    {
        st.pop();
        if (r == "true" && l == "true")
            st.push("true");
        else
            st.push("false");
    }
    if (op == "or")
    {
        st.pop();
        if (r == "false" && l == "false")
            st.push("false");
        else
            st.push("true");
    }

}

string evaluate(string* s, int cnt) {
    stack<string> st;
    stack<string> op;
    for (int i = 0; i < cnt; i++)
    {
        if (is_op(s[i]))
        {
            string cur_op = s[i];
            if (cur_op != "not")
                while (!op.empty() && priority(op.top()) >= priority(cur_op))
                {
                    process_op(st, op.top());
                    op.pop();
                }
            op.push(cur_op);
        }
        else {
            st.push(s[i]);
            while (!op.empty() && op.top() == "not")
            {
                process_op(st, op.top());
                op.pop();
            }
        }
    }
    while (!op.empty()) {
        process_op(st, op.top()); op.pop();
    }
    return st.top();
}
bool check(string* s, int cnt) {
    bool flag = true;
    if (s[0] == "or" || s[0] == "and" || s[cnt - 1] == "or" || s[cnt - 1] == "and" || s[cnt - 1] == "not")
    {
        flag = false;
        return flag;
    }
    for (int i = 0; i < cnt; i++)
    {
        if (s[i] == "not" && (s[i + 1] == "or" || s[i + 1] == "and"))
        {
            flag = false;
            return flag;
        }
    }
    int cnt2 = 0;
    for (int i = 0; i < cnt; i++)
    {
        if (s[i] == "or" || s[i] == "and")
            s2[cnt2++] = 1;
        else if (s[i] == "true" || s[i] == "false")
            s2[cnt2++] = 0;
        if (cnt2 >= 2 && (s2[cnt2 - 2] ^ 1) != s2[cnt2 - 1])
        {
            flag = false;
            return flag;
        }
    }
    return flag;
 }
int main()
{
    while (cin >> s[cnt])
        cnt++;
    if (!check(s, cnt))
    {
        cout << "error";
        return 0;
    }
    cout << evaluate(s, cnt);
    return 0;
}

二阶前缀和

#include<bits/stdc++.h> 

using namespace std;
const int N = 1010;
int a[N][N], s[N][N], ans;
using namespace std; 
int main()
{
	int n, r;
	cin >> n >> r;
	while (n--)
	{
		int x, y, w;
		cin >> x >> y >> w;
		x++;
		y++;
		a[x][y] += w;
	}
	for (int i = 1; i <= 1001; i++)
	{
		for (int j = 1; j <= 1001; j++)
		{
			s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
		}

	}
	for (int i = r; i <= 1001; i++)
	{
		for (int j = r; j <= 1001; j++)
		{
			ans = max(ans, s[i][j] - s[i - r][j] - s[i][j - r] + s[i - r][j - r]);
		}

	}
	cout << ans << endl;
	return 0;
}

矩形覆盖

#include <bits/stdc++.h>
using namespace std;
int n, ans,d,w;
stack<int> st;
int main(){
    cin >> n;
    for(int i=1; i <= n; i++){
        cin >> d >>w;
        while(!st.empty()&& w<= st.top()){
            if(st.top()== w)
                ans++;
            st.pop();
        }
        st.push(w);
    }
    cout <<n- ans;
    return 0;
}

多项式变化求值

#include<bits/stdc++.h> 
#define ll long long
const int MOD =99887765;
const int N=5e6 +7;
using namespace std;
stack<int> st;
int n,x,a[N],b[N];
ll ans;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin >> n >> x;
    for(int i=1;i<= n+ 1; i++){
        cin >> a[i];
        while(!st.empty()&& a[i]< a[st.top()]){
            b[st.top()]= a[i];
            st.pop();
        }
        st.push(i);
    }
    for(int i=1;i<=n+ 1; i++){
        ans =ans *x+ b[i];
        ans=(ans%MOD+MOD)%MOD;
    }
    cout << ans;
    return 0;
}

这项目我小码哥投了

#include<bits/stdc++.h> 

using namespace std;
const int N=1e3 + 7;
int n,m,a[N][N],ans;
char ch;
int maxRec(int x){
    int ret = 0;
    stack<int> s;
    s.push(0);
    for(int i=1;i<= m+1; i++){
        while(a[x][i]< a[x][s.top()]){
            int h= a[x][s.top()];
            s.pop();
            int w=i-s.top()- 1;
            ret = max(ret,w* h);
        }
       s.push(i);
    }
    return ret;
}
int main( )
{
    cin >> n >> m;
    for(int i=1;i<= n; i++)
        for(int j=1;j<= m; j++){
            cin >> ch;
            if(ch =='G')
                a[i][j] = 1;
        }
    for(int i=1; i<= n; i++)
        for(int j=1; j<= m; j++)
            if(a[i][j])
                a[i][j]+= a[i -1][j];
    for(int i=1; i <= n; i++)
        ans = max(ans,maxRec(i));
    cout << ans * 10;
    return 0;
}

山脉

#include<bits/stdc++.h> 

#define int long long
using namespace std;
int n,num,sum;
stack<int> stk;
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin >> n;
    for(int i=1; i<= n; i++){
        cin >> num;
        while(!stk.empty()&& stk.top()<= num)
            stk.pop();
        sum += stk.size();
        stk.push(num);  
    }   
    cout << sum;
    return 0;
}

区间修改

#include<bits/stdc++.h> 

using namespace std;

const int N=1e5 +10;
int n, a[N],sub[N],num1, num2;
int main(){
    int ans =0,buf = 0;
    cin >> n;
    for(int i=1; i<= n; i++)
        cin >> a[i];
    for(int i =2;i<=n; i++){
        sub[i]= a[i]-a[i -1];
        if(sub[i]> 0)
            num1 += sub[i];
        else
            num2 += sub[i];
    }
    cout << max(num1,-num2);
    return 0;
} 

相对马高

#include<bits/stdc++.h> 

using namespace std;
const int N=1e4 +10;
int n,h,f,g[N],sub[N],a, b;
int main(){
    cin >> n >> h >> f;
    sub[1] = h;
    while(f--){
        cin >> a >> b;
        if(a == b)
            continue;
        if(a > b)
            swap(a,b);
        sub[a + 1]-= 1;
        sub[b]+= 1;
    }
    for(int i=1; i<= n;i++){
        g[i]= g[i -1] + sub[i];
        cout << g[i]<< endl;
    }
    return 0;
 }   

小码哥处理订单

#include <bits/stdc++.h>
 using namespace std;
 typedef long long int ll;
 typedef unsigned long long int ull;
 #define all(a) a.begin(), a.end()
 #define rall(a) a.rbegin(), a.rend()
 #define fi first
 #define se second
 #define rep(i,s,n) for(int i=s;i<n;i++)
 #define repd(i,s,n) for(int i=s;i>=n;i--)
 const int MOD=1e9+7;
 const int maxN=5e3+1;
 const int INF=2e9;
 const int MB=20;
 const int MAX_LEN=1e6+10;
 ll a[MAX_LEN];
 ll f[MAX_LEN*4],v[MAX_LEN*4];
 inline void bulidtree(int k,int l,int r)
 {
 v[k]=0;
 if (l==r)
 {
 f[k]=0;
 return;
 }
 int mid=l+r>>1;
 bulidtree(k+k,l,mid);
 bulidtree(k+k+1,mid+1,r);
 f[k]=f[k+k]+f[k+k+1];
 }
 inline void insert(int k,int l,int r,int x,int y,int z)
 {
 if (l==x && r==y)
 {
 v[k]+=z;
 return;
 }
 f[k]+=(y-x+1)*z;
 int mid=l+r>>1;
 if (y<=mid)
 insert(k+k,l,mid,x,y,z);
 else
 if (x>mid)
 insert(k+k+1,mid+1,r,x,y,z);
 else
 insert(k+k,l,mid,x,mid,z),
 insert(k+k+1,mid+1,r,mid+1,y,z);
}
 ll query(int k,int l,int r,int x,int y,ll p)
 {
 p+=v[k];
 if (l==x && r==y)
 {
 return f[k]+p*(y-x+1);
 }
 int mid=l+r>>1;
 if (y<=mid)
 return query(k+k,l,mid,x,y,p);
 else
 if (x>mid)
 return query(k+k+1,mid+1,r,x,y,p);
 else
 return query(k+k,l,mid,x,mid,p)+query(k+k+1,mid+1,r,mid+1,y,p);

 }
 int z[MAX_LEN],x[MAX_LEN],y[MAX_LEN];
 void solve()
 {
 int n,m;
 cin>>n>>m;
 for (int i=1;i<=n;i++)
 cin>>a[i];
 for (int i=1;i<=m;i++)
 {
 cin>>z[i]>>x[i]>>y[i];
 for (int k=x[i];k<=y[i];k++)
 {
 a[k]-=z[i];
 if (a[k]<0)
 {
 cout<<-1<<"\n";
 cout<<i<<"\n";
 return;
 }
 }
 }
 cout<<0<<"\n";

 }
 int main()
 {
 solve();

 return 0;
 }

礼物

#include<bits/stdc++.h> 

using namespace std;

int cnt1, cnt2, x, y;

bool check(int num) {
    if (num - num / (x * y)<cnt1 + cnt2)
        return 0;
    if (num -num / x < cnt1)
        return 0;
    if (num - num / y < cnt2)
        return 0;
    return 1;
}

int main( ) {
    cin >> cnt1 >>cnt2 >>x>>y;
    int l =1, r= 2e9;
    int ans;
    int cnt =0;
    while (l <=r){
        int mid =l+(r-l)/2;
        if (check (mid))
            r=mid - 1, ans = mid;
        else
            l=mid +1;
    }
    printf("%d", ans);
    return 0;
}

区间按位与

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, m;
int mn[N][50], Lg[N], a[N], ans;
void pre()
{
    Lg[1] = 0;
    for (int i = 2; i <= n; i++)
    {
        Lg[i] = Lg[i >> 1] + 1;
    }
}
void ST_create()
{ // 创建ST表
    for (int i = 1; i <= n; i++)
    {
        mn[i][0] = a[i];
    }
    for (int j = 1; j <= Lg[n]; j++)
    {
        for (int i = 1; i <= n - (1 << j) + 1; i++)
        {
            mn[i][j] = mn[i][j - 1] & mn[i + (1 << (j - 1))][j - 1]; // 改成或运算
        }
    }
}
int ST_q(int l, int r)
{ // ST表求区间或
    int k = Lg[r - l + 1];
    return mn[l][k] & mn[r - (1 << k) + 1][k]; // 改成或运算
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    pre();
    ST_create();
    while(m--){
        int a1,a2;
        cin>>a1>>a2;
        cout<<ST_q(a1,a2)<<'\n';
    }
    return 0;
}

区间按位或

#include<bits/stdc++.h> 

using namespace std;

const int N = 2e5 +7;
int m, n, a[N], mn[N][50], Lg[N], ans;

void pre() {
    Lg[1] =0;
    for (int i=2; i<=n; i++)
        Lg[i]  = Lg[i >>1]+1;
}

void ST_create() {
    for (int i= 1; i <=n; i++)
        mn[i][0] =a[i];
    for (int j =1;j<= Lg[n];j++)
        for (int i = 1;i<=n-(1<<j)+1;i++)
            mn[i][j] =mn[i][j-1] | mn[i +(1<<(j-1))][j-1];
}

int ST_query(int l, int r) {
    int k = Lg[r -l+ 1];
    return mn[l][k] | mn[r - (1 << k) +1][k];
}


int main( )
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for (int i =1;i <=n; i++)
        cin >>a[i];
    pre();
    ST_create();
    while (m--){
        int a1, a2;
        cin >> a1>>a2;
        cout << ST_query(a1, a2) << '\n';
    }
    return 0;
}

松鼠接松果

#include<bits/stdc++.h> 

using namespace std;
const int N = 1e5 + 7;
int n,D,ans = 0x3f3f3f3f;
struct POS {
    int x,y;
    bool operator<(const POS &t) const { return x < t.x; }
} p[N];
deque<int> maxn,minn;

int main( )
{
    cin >> n >> D;
    for(int i=1;i<=n;i++)
        cin>>p[i].x>>p[i].y;
    sort(p+1,p+1+n);
    int L = 1;
    for(int i=1;i<=n;i++) {
        while(!maxn.empty() && p[maxn.back()].y<p[i].y)
            maxn.pop_back();
        maxn.push_back(i);
        while(!minn.empty() && p[minn.back()].y > p[i].y)
            minn.pop_back();
        minn.push_back(i);
        while(L < i && p[maxn.front()].y - p[minn.front()].y >= D) {
            ans = min(ans,p[i].x-p[L].x);
            L++;
            while(!maxn.empty() && maxn.front() < L)
                maxn.pop_front();
            while(!minn.empty() && minn.front() < L)
                minn.pop_front();
        }
    }
    if(ans == 0x3f3f3f3f)
        cout<<"-1";
    else
        cout << ans << endl;
    return 0;
}

排序

#include<bits/stdc++.h> 

using namespace std;
#define int long long
const int N = 2e5 +7;
int n, m, a[N], b[N], top;
struct NODE {
    int k, x;
}st[N];

signed main() {
    cin >>n>>m;
    for (int i=1; i<=n; i++) {
        cin >>a[i];
        b[i]=a[i];
    }
    while (m--){
        int k, x;
        cin >>k>>x;
        while (top && st[top].x <= x)
            top--;
        st[++top]={k,x};
    }
    int nn = st[1].x;
    sort(b +1,b+1+nn);
    int l=1,r=nn;
    st[top + 1].x =0;
    for(int i=1; i <= top; i++) {
        int t = st[i].x - st[i + 1].x;
        if (st[i].k == 1)
            while (t--)
                a[nn--]=b[r--];
        else
            while (t--)
                a[nn--]=b[l++];
    }
    for (int i=1;i<=n; i++)
        cout << a[i]<<" ";
    return 0;
}

区间最小值

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, m, a[N], mn[N][20], Lg[N], l, r;
void pre()
{
    Lg[1] = 0;
    for (int i = 2; i <= n; i++)
    {
        Lg[i] = Lg[i >> 1] + 1;
    }
}
void ST_create()
{ // 创建ST表
    for (int i = 1; i <= n; i++)
    {
        mn[i][0] = a[i];
    }
    for (int j = 1; j <= Lg[n]; j++)
    {
        for (int i = 1; i <= n - (1 << j) + 1; i++)
        {
            mn[i][j] = min(mn[i][j - 1], mn[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int ST_qmin(int l, int r)
{ // ST表求min
    int k = Lg[r - l + 1];
    return min(mn[l][k], mn[r - (1 << k) + 1][k]);
}
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    pre();
    ST_create();
    while (m--)
    {
        cin >> l >> r;
        cout << ST_qmin(l, r) << endl;
    }
    return 0;
}

区间gcd

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, m, a[N], mn[N][20], Lg[N], l, r, ans;
void pre()
{
    Lg[1] = 0;
    for (int i = 2; i <= n; i++)
    {
        Lg[i] = Lg[i >> 1] + 1;
    }
}
void ST_create()
{ // 创建ST表
    for (int i = 1; i <= n; i++)
    {
        mn[i][0] = a[i];
    }
    for (int j = 1; j <= Lg[n]; j++)
    {
        for (int i = 1; i <= n - (1 << j) + 1; i++)
        {
            mn[i][j] = gcd(mn[i][j - 1], mn[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int ST_qgcd(int l, int r)
{ // ST表求gcd
    int k = Lg[r - l + 1];
    return gcd(mn[l][k], mn[r - (1 << k) + 1][k]);
}
// 快读快写:
int read()
{
    int ret = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9')
        ch = getchar();
    while (ch >= '0' && ch <= '9')
    {
        ret = ret * 10 + ch - '0';
        ch = getchar();
    }
    return ret;
}
void write(int x)
{
    if (x >= 10)
        write(x / 10);
    putchar(x % 10 + '0');
}
int main()
{
    n = read(), m = read();
    for (int i = 1; i <= n; i++)
        a[i] = read();
    pre();
    ST_create();
    while (m--)
    {
        l = read(), r = read();
        ans = ST_qgcd(l, r);
        write(ans);
        putchar('\n');
    }
    return 0;
}

史莱姆融合

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, fa[N], so[N], nxt[N]; // fa:集合最左元素 so:集合最右元素
void init(int n)
{
    for (int i = 1; i <= n; i++)
    {
        fa[i] = i;
        so[i] = i;
    }
}
int find(int x)
{
    if (fa[x] != x)
        fa[x] = find(fa[x]);
    return fa[x];
}
 
void merge(int i, int j)
{
    int x = find(i), y = find(j);
    if (x == y)
        return;
    nxt[so[x]] = y; // x集合的最右元素指向y集合的最左元素
    fa[y] = x;      // y集合的最左元素更新为x集合的最左元素
    so[x] = so[y];  // x集合的最右元素更新为y集合的最右元素
}
 
int main()
{
    cin >> n;
    init(n);
    for (int i = 1; i <= n - 1; i++)
    {
        int x, y;
        cin >> x >> y;
        merge(x, y);
    }
    for (int i = find(1); i; i = nxt[i])
    { // 这里int i=find几也行,因为最后find()总是返回链表最左边的元素
        cout << i << ' ';
    }
 
    return 0;
}

检测敌人


#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
struct enemy
{
    double x, y, r, l;
    bool v;
} e[N];
bool cmp(enemy a, enemy b)
{
    return a.r < b.r;
}
int main()
{
    int n;
    double r;
    while (cin >> n >> r && !(n == 0 && r == 0))
    {
        bool flag = false;
        memset(e, 0, sizeof e);
        for (int i = 1; i <= n; i++)
        {
            cin >> e[i].x >> e[i].y;
            if (r * r < e[i].y * e[i].y) // 不可覆盖
            {
                flag = true;
            }
            else
            { // 求在x轴上的投影
                e[i].l = e[i].x - sqrt(r * r - e[i].y * e[i].y);
                e[i].r = sqrt(r * r - e[i].y * e[i].y) + e[i].x;
                e[i].v = false;
            }
        }
        if (flag)
        { // 以敌人为中心,r为半径的圆与x无交点:不可覆盖
            cout << -1 << endl;
            continue;
        }
        sort(e + 1, e + 1 + n, cmp);
        int ans = 0;
        for (int i = 1; i <= n; i++)
        { // 从小到大检测每一条线段
            if (e[i].v == false)
            { // 此敌人还未被检测
                for (int j = i; j <= n; j++)
                {
                    if (e[j].v == false && e[j].l <= e[i].r) // 未被检测的敌人线段与当前线段有交集
                    {
                        e[j].v = true;
                    }
                }
                e[i].v = true;
                ans++;
            }
        }
        cout << ans << endl;
    }
 
    return 0;
}

小码哥的福利

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 55;
ll n, m, a[N], sum[N];
struct tianpin
{
	ll b, c;
} t[N];
int cmp(tianpin x, tianpin y)
{ // 甜品甜度由小到大排序
	return x.b < y.b;
}
ll add(int l, int r)
{ // 计算sum[l]到sum[r]的和
	ll ans = 0;
	for (int i = l; i <= r; i++)
	{
		ans += sum[i];
	}
	return ans;
}
 
int main()
{
	cin >> n;
	ll maxn = 0; // 最高耐受度
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		maxn = max(maxn, a[i]);
	}
	sort(a + 1, a + n + 1);
	cin >> m;
	for (int i = 1; i <= m; i++)
	{
		cin >> t[i].b;
		if (t[i].b > maxn) // 此甜品没有能容忍的人
		{
			cout << -1 << endl;
			return 0;
		}
	}
	for (int i = 1; i <= m; i++)
	{
		cin >> t[i].c;
	}
	sort(t + 1, t + n + 1, cmp);
	for (int i = 1; i <= m; i++)
	{ // sum数组赋初值,每个甜品找第一个能吃的人
		for (int j = 1; j <= n; j++)
		{
			if (a[j] >= t[i].b)
			{
				sum[j] += t[i].c;
				break;
			}
		}
	}
	for (int i = 1; i <= n; i++)
	{ // 平均化
		ll tmp = (add(i, n)) / (n - i + 1);
		if (tmp <= sum[i])
		{ // 此人分配的甜品过多->分给右边的人
			sum[i + 1] += sum[i] - tmp;
			sum[i] = tmp;
		}
	}
	ll ans = 0;
	for (int i = 1; i <= n; i++)
	{
		ans = max(ans, sum[i]);
	}
	cout << ans << endl;
	return 0;
}

屠龙勇者

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5 + 10;
int n, m;
int d[N];
int w[N];
int v[N]; // 勇士是否被使用
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
	{
		cin >> d[i];
	}
	sort(d + 1, d + 1 + n);
	for (int i = 1; i <= m; i++)
	{
		cin >> w[i];
	}
	sort(w + 1, w + 1 + m);
	int j = 1;
	for (int i = 1; i <= n; i++)
	{ // d
		int flag = 0;
		for (; j <= m; j++)
		{ // w
			// 找第一个>=d的w
			if (v[j] == 0 && w[j] >= d[i])
			{
				v[j] = 1;
				flag = 1;
				break;
			}
		}
		if (flag == 0)
		{ // 有头没有勇士能消灭
			cout << "NO" << endl;
			return 0;
		}
	}
	cout << "YES" << endl;
 
	return 0;
}

外卖递送

#include<bits/stdc++.h> 

using namespace std;
#define int long long
const int N=1e5+10;
int a[N];
signed main( )
{
    int n;
    int ans=0;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++)
    {
        int k=n-i+1;
        if(a[k]>a[i]) ans+=a[k]-a[i];
        else break;
    }
    cout<<ans<<endl;

    return 0;
}

奇偶序列

#include<bits/stdc++.h> 

using namespace std;

int main( )
{   
    int n;
    cin >> n;
    // 初始数据
    vector<int> a(n);
    // 用来存储奇数和偶数
    vector<int> odd;
    vector<int> even;
    // p_odd和p_even用来存储奇数和偶数原先的位置
    vector<int> p_odd;
    vector<int> p_even;
    for(int i=0; i<n; ++i){
        cin >> a[i];
        if(a[i]%2==0){
            even.push_back(a[i]);
            p_even.push_back(i);
        }
        else{
            odd.push_back(a[i]);
            p_odd.push_back(i);
        }
    }
    // 排序
    sort(odd.begin(),odd.end());
    sort(even.begin(),even.end());
    // 将排序后的奇数偶数对应放回原来的位置
    for(int i=0; i<p_odd.size(); ++i){
        a[p_odd[i]] = odd[i];
    }
    for(int i=0; i<p_even.size(); ++i){
        a[p_even[i]] = even[i];
    }

    for(int i=0; i<a.size(); ++i){
        cout << a[i] << " ";
    }

    return 0;
}

小码哥的跳棋游戏新编

#include<bits/stdc++.h> 

using namespace std;

const int N = 100005;
int e[N], n, c1;

int main( )
{
    cin >> n;
    cin >> e[1];
    
    for(int i = 2; i <= n; i++){
        cin >> e[i];
        // 画图模拟几种情况试一试就可以知道
        // 遇到如下情况的时候,拔掉当前的旗子就是最优解了
        // 可以试一试如下序列:
        // 1 2 1 2 0 2 2 2 0
        // 0 2 1 2 0 2 2 2 0
        // 1 2 1 2 1 2 2 2 0
        // 我用这三个序列得出的贪心结论代码如下
        if(e[i] != 0 && e[i - 1] != 0 && e[i] != e[i - 1]){
            e[i] = 0;
            ++c1;
        }
    }
    cout << c1;
    return 0;
}

能量供应

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
typedef long long ll;
int st[N],res; 
struct node{
    int l,r,t;
}a[N];
bool cmp(node x,node y){
    return x.r<y.r;
}
int main(){
    int n,b;
    cin>>n>>b;
    for(int i=1;i<=b;i++)cin>>a[i].l>>a[i].r>>a[i].t;
    sort(a+1,a+1+b,cmp);
    for(int i=1;i<=b;i++){
        int cnt = 0;
        for(int j=a[i].l;j<=a[i].r;j++)if(st[j])cnt++;
        if(cnt>=a[i].t)continue;
        for(int j = a[i].r;j>=a[i].l;j--){
            if(!st[j]){
                st[j]=1;cnt++;res++;
            if(cnt==a[i].t)break;
            }
        }
    }
    cout<<res<<endl;
}

小码哥的布阵指挥

#include<bits/stdc++.h> 

using namespace std;

const int N = 1005;
int a[N], b[N],n, x;

// 插入排序
int main( )
{
    cin >> n >> x;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    b[1] = a[1];
    for(int i = 2; i <= n; i++){
        // 先对原来的数组进行前i-1个数的局部排序
        sort(a, a + i);
        for(int j = 1; j < i; j++){
            // 挨个对比
            if(abs(a[i] - a[j]) < x)
            {
                a[i] = a[j] + x;
            }
            b[i] = a[i];
        }
    }
    for(int i = 1; i <= n; i++)
        cout << b[i] << ' ';  
    return 0;
}

活动分组

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
pii p[100005];
multiset<pii> s;
inline int read(){
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9'){
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9'){
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}
int main() {
    int n;
    ll suma = 0, sumb = 0;
    n = read();
    int m = n / 2;
    for (int i = 1; i <= n; ++i) {
        p[i].first = read();
        suma += p[i].first;
    }
    for (int i = 1; i <= n; ++i) {
        p[i].second = read();
        sumb += p[i].second;
    }
    if (suma % m != 0 || sumb % m != 0) {
        cout << "NO" << endl;
        return 0;
    }
    suma /= m, sumb /= m;
    for (int i = 1; i <= n; ++i) s.insert(p[i]);
    for (int i = 1; i <= n; ++i) {
        if (s.empty()) break;
        if (s.find(p[i]) == s.end()) continue;
        auto it = s.find(p[i]);
        s.erase(it);
        pii q = {suma - p[i].first, sumb - p[i].second};
        if (s.find(q) == s.end()) {
            cout << "NO" << endl;
            return 0;
        }
        it = s.find(q);
        s.erase(it);
    }
    cout << "YES" << endl;
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
06-01
这道题是一道典型的费用限制最短路题目,可以使用 Dijkstra 算法或者 SPFA 算法来解决。 具体思路如下: 1. 首先,我们需要读入输入数据。输入数据中包含了道路的数量、起点和终点,以及每条道路的起点、终点、长度和限制费用。 2. 接着,我们需要使用邻接表或邻接矩阵来存储图的信息。对于每条道路,我们可以将其起点和终点作为一个有向边的起点和终点,长度作为边权,限制费用作为边权的上界。 3. 然后,我们可以使用 Dijkstra 算法或 SPFA 算法求解从起点到终点的最短路径。在这个过程中,我们需要记录到每个点的最小费用和最小长度,以及更新每条边的最小费用和最小长度。 4. 最后,我们输出从起点到终点的最短路径长度即可。 需要注意的是,在使用 Dijkstra 算法或 SPFA 算法时,需要对每个点的最小费用和最小长度进行松弛操作。具体来说,当我们从一个点 u 经过一条边 (u,v) 到达另一个点 v 时,如果新的费用和长度比原来的小,则需要更新到达 v 的最小费用和最小长度,并将 v 加入到优先队列(Dijkstra 算法)或队列(SPFA 算法)中。 此外,还需要注意处理边权为 0 或负数的情况,以及处理无法到达终点的情况。 代码实现可以参考以下样例代码: ```c++ #include <cstdio> #include <cstring> #include <queue> #include <vector> using namespace std; const int MAXN = 1005, MAXM = 20005, INF = 0x3f3f3f3f; int n, m, s, t, cnt; int head[MAXN], dis[MAXN], vis[MAXN]; struct Edge { int v, w, c, nxt; } e[MAXM]; void addEdge(int u, int v, int w, int c) { e[++cnt].v = v, e[cnt].w = w, e[cnt].c = c, e[cnt].nxt = head[u], head[u] = cnt; } void dijkstra() { priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q; memset(dis, 0x3f, sizeof(dis)); memset(vis, 0, sizeof(vis)); dis[s] = 0; q.push(make_pair(0, s)); while (!q.empty()) { int u = q.top().second; q.pop(); if (vis[u]) continue; vis[u] = 1; for (int i = head[u]; i != -1; i = e[i].nxt) { int v = e[i].v, w = e[i].w, c = e[i].c; if (dis[u] + w < dis[v] && c >= dis[u] + w) { dis[v] = dis[u] + w; q.push(make_pair(dis[v], v)); } } } } int main() { memset(head, -1, sizeof(head)); scanf("%d %d %d %d", &n, &m, &s, &t); for (int i = 1; i <= m; i++) { int u, v, w, c; scanf("%d %d %d %d", &u, &v, &w, &c); addEdge(u, v, w, c); addEdge(v, u, w, c); } dijkstra(); if (dis[t] == INF) printf("-1\n"); else printf("%d\n", dis[t]); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值