2019 Multi-University Training Contest 8

1003 - Acesrc and Good Numbers

分析:首先f(n,d)可以在log的时间内算出来。

对于给定的n和d,如果f(n,d)==n,那么直接就是答案,如果f(n,d)<n,我们知道f(n,d)是单调函数,那么f(n,d)==n的数字肯定不会在f(n,d) 到 n之间出现,那么之间让n=f(n,d)就可以了,如果f(n,d)>n,我们知道,当n减少1,f(n,d)最多减少m,m是n的位数,那么n直接减掉(f(n,d)-n) / m就可以了。

#include "bits/stdc++.h"

using namespace std;
unsigned long long a[20];
unsigned long long dig[10];
unsigned long long bas[19];

unsigned long long f(unsigned long long n, int d) {
    unsigned long long base = 1;
    int cnt = 1;
    while (base * 10 <= n) {
        cnt++;
        base *= 10;
    }
    while (base) {
        int t = n / base;
        dig[d] += a[cnt - 1] * t;
        if (t - 1 >= d) dig[d] += bas[cnt - 1];
        if (t == d) {
            dig[t] += n % base;
            dig[t]++;
        }
        n %= base;
        base /= 10;
        cnt--;
    }
}

int main() {
    bas[0] = 1;
    for (int i = 1; i <= 18; ++i) {
        bas[i] = bas[i - 1] * 10;
    }
    a[1] = 1;
    for (int i = 2; i <= 18; ++i) {
        a[i] = a[i - 1] * 10 + bas[i - 1];
    }
    int t;
    cin >> t;
    while (t--) {
        unsigned long long x, d;
        cin >> d >> x;
        dig[d] = 0;
        f(x, d);
        while (dig[d] != x) {
            if (x > dig[d])x = dig[d];
            else {
                int cnt = 0;
                unsigned long long temp = x;
                while (temp)cnt++, temp /= 10;
                x -= max((unsigned long long) 1, (dig[d] - x) / cnt);
            }
            dig[d] = 0;
            f(x, d);
        }
        printf("%llu\n", x);
    }
}

1004 - Acesrc and Hunting

分析:当搜索到一个点时,把这个点的所有后继找出来,然后计算这些点的后继,从后继最少的点开始搜。

#include "bits/stdc++.h"

using namespace std;
int f[20][2] = {0, 2, 0, -2, 2, 0, -2, 0, 1, 1, 1, -1, -1, 1, -1, -1, 1, 2, 1, -2, -1, 2, -1, -2, 2, 1, 2, -1, -2, 1,
                -2, -1, 2, 2, 2, -2, -2, 2, -2, -2};
int n, m;
bool vis[104][104];
vector<pair<int, int>> v;

struct node {
    int num, x, y;

    bool friend operator<(node a, node b) {
        return a.num < b.num;
    }
};

bool inmp(int x, int y) {
    return x >= 1 && x <= n && y >= 1 && y <= m;
}

void dfs(int x, int y) {
    if (v.size() == n * m)return;
    int tx, ty;
    vector<node> tt;
    for (int i = 0; i < 20; ++i) {
        tx = x + f[i][0];
        ty = y + f[i][1];
        if (!inmp(tx, ty))continue;
        if (vis[tx][ty])continue;
        int num = 0;
        for (int j = 0; j < 20; ++j) {
            int ttx = tx + f[j][0];
            int tty = ty + f[j][1];
            if (!inmp(ttx, tty))continue;
            if (vis[ttx][tty])continue;
            num++;
        }
        tt.push_back({num, tx, ty});
    }
    if (tt.size() == 0)return;
    sort(tt.begin(), tt.end());
    for (int i = 0; i < tt.size(); ++i) {
        vis[tt[i].x][tt[i].y] = 1;
        v.push_back(make_pair(tt[i].x, tt[i].y));
        dfs(tt[i].x, tt[i].y);
        if (v.size() == n * m)return;
        v.erase(--v.end());
        vis[tt[i].x][tt[i].y] = 0;

    }
}

int main() {
    int t;
    cin >> t;
    while (t--) {
        cin >> n >> m;
        v.clear();
        memset(vis, 0, sizeof(vis));
        vis[1][1] = 1;
        v.push_back(make_pair(1, 1));
        dfs(1, 1);
        if (v.size() == n * m) {
            puts("YES");
            for (int i = 0; i < v.size(); ++i) {
                printf("%d %d\n", v[i].first, v[i].second);
            }
        } else puts("NO");
    }
}

1005 - Acesrc and String Theory

分析:首先此题与poj3693类似。

简单说一下做法,题目的要求等效于求所有子串中,是由k个循环节组成的子串的个数。那么我们枚举这个循环节的长度,设为L。显然,此时我们需要找出循环节长度为L的所有子串,假如存在一个循环次数>=2的子串,那么一定有:s[i*L] == s[(i+1)*L]的这样一组pair被包含在里面,并且长度是由他们的最长公共前缀和最长公共后缀决定,即,我们枚举s[0],s[L],s[2*L]……相邻的两个,然后求两次lcp就可以得到循环的次数。设这个子串的长度为len,那么显然,对答案的贡献应该是len - k*L + 1。

不考虑lcp的复杂度,循环次数应该是n + n/2 + n/3 + …… ≈ nlogn。

可以构造两个后缀数组来求lcp,也是比较套路的做法。构建一个正常的后缀数组,求后缀的最长公共前缀,一个将字符串反过来的后缀数组,求前缀的最长公共后缀。求p1,p2两个后缀的lcp就是height数组在rk[p1]+1到rk[p2]之间的最小值,建个ST表就可以了。

或者直接hash求lcp,由于满足单调关系,直接二分就可以了。

hash+二分代码:

#include "bits/stdc++.h"

using namespace std;
int n;
char s[300004];
unsigned long long Hash[300004];
unsigned long long base[300004];

unsigned long long geth(int l, int r) {
    if (l == 0)return Hash[r];
    else return Hash[r] - Hash[l - 1] * base[r - l + 1];
}

int getpre(int pos1, int pos2) {
    int l = 0, r = min(pos1, pos2);
    int ans = 0;
    while (l <= r) {
        int mid = l + r >> 1;
        unsigned long long temp1 = geth(pos1 - mid, pos1);
        unsigned long long temp2 = geth(pos2 - mid, pos2);
        if (temp1 == temp2) {
            ans = mid;
            l = mid + 1;
        } else r = mid - 1;
    }
    return ans;
}

int getlas(int pos1, int pos2) {
    int l = 0, r = min(n - 1 - pos1, n - 1 - pos2);
    int ans = 0;
    while (l <= r) {
        int mid = l + r >> 1;
        unsigned long long temp1 = geth(pos1, pos1 + mid);
        unsigned long long temp2 = geth(pos2, pos2 + mid);
        if (temp1 == temp2) {
            ans = mid;
            l = mid + 1;
        } else r = mid - 1;
    }
    return ans;
}

int main() {
    int t;
    cin >> t;
    base[0] = 1;
    for (int i = 1; i < 300004; ++i) {
        base[i] = base[i - 1] * 233;
    }
    while (t--) {
        int k;
        scanf("%d", &k);
        scanf("%s", s);
        n = strlen(s);
        if (k == 1) {
            ans = 1LL * n * (n + 1) / 2;
            cout << ans << endl;
            continue;
        }

        Hash[0] = s[0] - 'a';
        for (int i = 1; i < n; ++i) {
            Hash[i] = Hash[i - 1] * 233 + s[i] - 'a';
        }
        long long ans = 0;

        for (int L = 1; L <= n / k; ++L) {
            int l = 0, r = L;
            while (r < n) {
                if (s[l] == s[r]) {
                    int lenl = getpre(l, r), lenr = getlas(l, r);
                    int len = lenl + lenr + L + 1;
                    if (len >= k * L) {
                        ans += len - k * L + 1;
                    }
                    lenr += r;
                    while (l <= lenr)
                        l += L, r += L;
                } else l += L, r += L;
            }
        }
        cout << ans << endl;
    }

}

后缀数组+rmq代码:

#include "bits/stdc++.h"
using namespace std;
struct hasaki{
    int n,m;
    char s[300010];
    int sa[300010],x[300010],y[300010],c[300010],height[300010],rk[300010];
    int dp[300010][40];
    void Suffix(){
        for(int i=0;i<m;i++) c[i]=0;
        for(int i=0;i<n;i++) c[x[i]=s[i]]++;
        for(int i=0;i<m;i++) c[i]+=c[i-1];
        for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
        for(int k=1;k<=n;k<<=1) {
            int p=0;
            for(int i=n-k;i<n;i++) y[p++]=i;
            for(int i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
            for(int i=0;i<m;i++) c[i]=0;
            for(int i=0;i<n;i++) c[x[y[i]]]++;
            for(int i=0;i<m;i++) c[i]+=c[i-1];
            for(int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
            swap(x,y);
            p=1;x[sa[0]]=0;
            for(int i=1;i<n;i++)
                x[sa[i]]= y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++;
            if(p>=n) break;
            m=p;
        }
    }
    void getheight(){
        for(int i=0;i<n;i++) rk[sa[i]]=i;
        for(int i=0,k=0;i<n;i++){
            if(rk[i]){
                if(k) --k;
                else k=0;
                int j=sa[rk[i]-1];
                while(s[i+k]==s[j+k])
                    k++;
                height[rk[i]]=k;
            }
        }
    }
    void init(){
        for (int i = 0; i < n; ++i) {
            dp[i][0]=height[i];
        }
        for (int j = 1; (1<<j) < n; ++j) {
            for (int i = 0; i + (1<<j) - 1 < n; ++i) {
                dp[i][j]=0x3f3f3f3f;
                dp[i][j]=min(dp[i][j-1],dp[i+(1<<j-1)][j-1]);
            }
        }
    }
    int que(int l,int r){
        if(l>r)swap(l,r);
        l++;
        int k = log2(r-l+1);
        return min(dp[l][k],dp[r-(1<<k)+1][k]);
    }
    int getlcp(int l,int r){
        return que(rk[l],rk[r]);
    }
}pre,las;

int main(){
    int t;
    cin>>t;
    while(t--){
        int k;
        scanf("%d%s",&k,las.s);
        int n = strlen(las.s);
        for (int i = 0; i < n; ++i) {
            pre.s[i] = las.s[n-1-i];
        }
        if(k == 1)
        {
            printf("%lld\n",1LL * n * (n + 1) / 2);
            continue;
        }
        pre.s[n] = las.s[n] = 0;
        pre.n = las.n = n + 1;
        pre.m = las.m = 128;
        pre.Suffix();
        las.Suffix();
        pre.getheight();
        las.getheight();
        pre.init();
        las.init();
        long long ans = 0;
        for (int L = 1; L <= n/k; ++L) {
            int l = 0,r = L;
            while (r < n){
                if(las.s[l] == las.s[r]){
                    int lenl = pre.getlcp(n-1-l,n-1-r);
                    int lenr = las.getlcp(l,r);
                    int len = lenl + lenr + L - 1;
                    if(len >= k*L){
                        ans += len - k*L + 1;
                    }
                    lenr += r;
                    while(l<=lenr){
                        l += L, r +=L;
                    }
                }
                else l += L,r += L;
            }
        }
        cout<<ans<<endl;
    }
}

1006 - Acesrc and Travel

分析:首先随便找一个根,然后就很容易找出,以这个根为起点,每个节点向下的先后和后手(相当于给节点加权后的最大值和最小值)的最优和次优解。然后在根据最优解和次优解找出每个节点向上的最优解,最后遍历一遍节点就可以得到答案了。

大概就是这么个套路,注意一下细节就可以过了。

#include "bits/stdc++.h"

using namespace std;
long long a[100004], b[100004];
vector<long long> v[100004];
pair<long long, long long> dpnxt[100004][2];//1min 0max
long long dppre[100004][2];

long long dfs1(long long u, long long pre, long long now) {
    if (v[u].size() == 1 && pre != -1) {
        dpnxt[u][now] = make_pair(0, 1e18);
        return a[u] - b[u];
    }
    long long res = -1e18;
    if (now)res = 1e18;
    vector<long long> tt;
    for (int i = 0; i < v[u].size(); ++i) {
        if (v[u][i] == pre)continue;
        if (now) {
            long long temp = dfs1(v[u][i], u, now ^ 1);
            if (tt.size() < 2)tt.push_back(temp);
            else {
                tt.push_back(temp);
                sort(tt.begin(), tt.end());
                tt.erase(--tt.end());
            }
            res = min(temp, res);
        } else {
            long long temp = dfs1(v[u][i], u, now ^ 1);
            if (tt.size() < 2)tt.push_back(temp);
            else {
                tt.push_back(temp);
                sort(tt.begin(), tt.end());
                tt.erase(tt.begin());
            }
            res = max(temp, res);
        }
    }
    if (tt.size() == 2)
        dpnxt[u][now] = make_pair(tt[0], tt[1]);
    else
        dpnxt[u][now] = make_pair(tt[0], 1e18);
    return res + a[u] - b[u];
}

long long txdy;

void dfs2(int u, int pre) {
    if (pre != -1) {
        vector<long long> tt;
        tt.push_back(dpnxt[pre][1].first);
        tt.push_back(dpnxt[pre][1].second);
        sort(tt.begin(), tt.end());
        for (int i = 0; i < tt.size(); ++i) {
            if (tt[i] == 1e18 || tt[i] == -1e18) {
                tt.erase(tt.begin() + i);
                i--;
            }
        }
        if (tt.size() == 1) {
            long long tmaxi = -1e18;
            if (dpnxt[u][0].first != 1e18 && dpnxt[u][0].first != -1e18)tmaxi = max(tmaxi, dpnxt[u][0].first);
            if (dpnxt[u][0].second != 1e18 && dpnxt[u][0].second != -1e18)tmaxi = max(tmaxi, dpnxt[u][0].second);
            if (tmaxi + a[u] - b[u] != tt[0])
                dppre[u][0] = min(tt[0] + a[pre] - b[pre], dppre[pre][1] + a[pre] - b[pre]);
            else
                dppre[u][0] = a[pre] - b[pre] + ((dppre[pre][1] == 1e18 || dppre[pre][1] == -1e18) ? 0 : dppre[pre][1]);
        } else {
            long long tmaxi = -1e18;
            if (dpnxt[u][0].first != 1e18 && dpnxt[u][0].first != -1e18)tmaxi = max(tmaxi, dpnxt[u][0].first);
            if (dpnxt[u][0].second != 1e18 && dpnxt[u][0].second != -1e18)tmaxi = max(tmaxi, dpnxt[u][0].second);
            if (tmaxi + a[u] - b[u] == tt[0])
                dppre[u][0] = min(tt[1] + a[pre] - b[pre], dppre[pre][1] + a[pre] - b[pre]);
            else dppre[u][0] = min(tt[0] + a[pre] - b[pre], dppre[pre][1] + a[pre] - b[pre]);
        }


        tt.clear();
        tt.push_back(dpnxt[pre][0].first);
        tt.push_back(dpnxt[pre][0].second);
        sort(tt.begin(), tt.end());
        for (int i = 0; i < tt.size(); ++i) {
            if (tt[i] == 1e18 || tt[i] == -1e18) {
                tt.erase(tt.begin() + i);
                i--;
            }
        }
        if (tt.size() == 1) {
            long long tmini = 1e18;
            if (dpnxt[u][1].first != 1e18 && dpnxt[u][1].first != -1e18)tmini = min(tmini, dpnxt[u][1].first);
            if (dpnxt[u][1].second != 1e18 && dpnxt[u][1].second != -1e18)tmini = min(tmini, dpnxt[u][1].second);
            if (tmini + a[u] - b[u] != tt[0])
                dppre[u][1] = max(tt[0] + a[pre] - b[pre], dppre[pre][0] + a[pre] - b[pre]);
            else
                dppre[u][1] = a[pre] - b[pre] + ((dppre[pre][0] == 1e18 || dppre[pre][0] == -1e18) ? 0 : dppre[pre][0]);
        } else {
            long long tmini = 1e18;
            if (dpnxt[u][1].first != 1e18 && dpnxt[u][1].first != -1e18)tmini = min(tmini, dpnxt[u][1].first);
            if (dpnxt[u][1].second != 1e18 && dpnxt[u][1].second != -1e18)tmini = min(tmini, dpnxt[u][1].second);

            if (tmini + a[u] - b[u] == tt[1])
                dppre[u][1] = max(tt[0] + a[pre] - b[pre], dppre[pre][0] + a[pre] - b[pre]);
            else dppre[u][1] = max(tt[1] + a[pre] - b[pre], dppre[pre][0] + a[pre] - b[pre]);
        }
    }
    for (int i = 0; i < v[u].size(); ++i) {
        if (v[u][i] == pre)continue;
        dfs2(v[u][i], u);
    }
}

int main() {
    int t;
    cin >> t;
    while (t--) {
        long long n;
        scanf("%lld", &n);
        txdy = -1e18;
        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &a[i]);
            dppre[i][1] = 1e18;
            dppre[i][0] = -1e18;
            v[i].clear();
        }
        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &b[i]);
        }
        int x, y;
        for (int i = 0; i < n - 1; ++i) {
            scanf("%d%d", &x, &y);
            v[x].push_back(y);
            v[y].push_back(x);
        }
        dfs1(1, -1, 0);
        dfs1(1, -1, 1);
        dfs2(1, -1);
        for (int i = 1; i <= n; ++i) {
            vector<long long> tt;
            if (v[i].size() > 1 || i == 1) {
                tt.push_back(dpnxt[i][1].second);
                tt.push_back(dpnxt[i][1].first);
            }
            tt.push_back(dppre[i][1]);
            sort(tt.begin(), tt.end());
            for (int j = 0; j < tt.size(); ++j) {
                if (tt[j] == 1e18 || tt[j] == -1e18)continue;
                txdy = max(txdy, tt[j] + a[i] - b[i]);
                break;
            }
        }
        printf("%lld\n", txdy);
    }
}

1009 - Calabash and Landlord

分析:枚举情况,然后暴力判断(智障做法

其实可以直接离散化后每个点块跑dfs,就可以求出有几个联通块,就是答案。。。

这里就贴一个智障代码口八。。

#include "bits/stdc++.h"

using namespace std;

bool bhd(int x1, int y1, int x2, int y2, int px, int py){
    return px > x1 && py > y1 && px < x2 && py < y2;
}
bool bhd1(int x1, int y1, int x2, int y2, int px, int py){
    return px >= x1 && py >= y1 && px <= x2 && py <= y2;
}
bool x_2(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4){
    return x1 == x3 && y1 == y3 && x2 == x4 && y2 == y4;
}

bool x_3(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4){
    bool flag = 0;
    flag |= (!bhd(x1, y1, x2, y2, x3, y3)
             && !bhd(x1, y1, x2, y2, x4, y4)
             && !bhd(x1, y1, x2, y2, x3, y4)
             && !bhd(x1, y1, x2, y2, x4, y3) );
    return flag;
}
bool x_31(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4){
    return bhd1(x1, y1, x2, y2, x3, y3) &&  bhd1(x1, y1, x2, y2, x4, y4);
}
bool x_4(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4){
    bool flag = false;
    flag |= (x1 == x3 && y1 == y3 && y2 < y4 && x2 > x4);
    flag |= (x1 < x3 && y1 == y3 && x2 == x4 && y2 < y4);
    flag |= (x1 == x3 && y1 > y3 && x2 > x4 && y2 == y4);
    flag |= (x1 < x3 && y1 > y3 && x2 == x4 && y2 == y4);

    flag |= (x1 < x3 && y1 == y3 && x2 > x3 && y2 == y4 && x2 < x4);
    flag |= (x1 == x3 && x2 == x4 && y1 < y4 && y1 > y3 && y2 > y4);

    flag |= (x1 > x3 && x2 < x4 && y1 == y3 && y2 == y4);
    flag |= (x1 == x3 && x2 == x4 && y1 > y3 && y2 < y4);
    return flag;
}

bool x_5(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4){
    bool flag = false;
    flag |= (x1 < x3 && x2 > x4 && y1 == y3 && y2 < y4);
    flag |= (x1 == x3 && x2 < x4 && y1 < y3 && y2 > y4);
    flag |= (x1 < x3 && x2 > x4 && y1 > y3 && y2 == y4);
    flag |= (x1 > x3 && x2 == x4 && y1 < y3 && y2 > y4);
    return flag;
}

bool x_6(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4){
    return x1 < x3 && x2 > x4 && y1 > y3 && y2 < y4;
};

int main(){
    int T; cin >> T;
    while( T --) {
        int x1, x2, x3, x4, y1, y2, y3, y4;
        cin >> x1 >> y1 >> x2 >> y2;
        cin >> x3 >> y3 >> x4 >> y4;
        int ans = 4;
        if(x_2(x1, y1, x2, y2, x3, y3, x4, y4)) ans = 2;
        else if(x_6(x1, y1, x2, y2, x3, y3, x4, y4) || x_6(x3, y3, x4, y4, x1, y1, x2, y2)) ans = 6;
        else if(x_5(x1, y1, x2, y2, x3, y3, x4, y4) || x_5(x3, y3, x4, y4, x1, y1, x2, y2)) ans = 5;
        else if(x_4(x1, y1, x2, y2, x3, y3, x4, y4) || x_4(x3, y3, x4, y4, x1, y1, x2, y2)) ans = 4;
        else if(x_3(x1, y1, x2, y2, x3, y3, x4, y4) && x_3(x3, y3, x4, y4, x1, y1, x2, y2)) ans = 3;
        else if(x_31(x1, y1, x2, y2, x3, y3, x4, y4) || x_31(x3, y3, x4, y4, x1, y1, x2, y2)) ans = 3;
        printf("%d\n", ans);
    }
    return 0;
}

1010 - Quailty and CCPC

分析:sort一下就可以了。

#include "bits/stdc++.h"
using namespace std;
struct node{
    int name;
    int num,time;
    bool friend operator < (node a,node b){
        if(a.num == b.num)return a.time < b.time;
        return a.num > b.num;
    }
}a[100004];
char s[100005][20];
int main(){
    int t;
    cin>>t;
    while(t--){
        int n,p,num,time;
        cin>>n>>p;
        for (int i = 0; i < n; ++i) {
            scanf("%s",s[i]);
            scanf("%d%d",&num,&time);
            a[i] = {i,num,time};
        }
        int temp = n*p;
        if(temp % 10 != 5)puts("Quailty is very great");
        else {
            sort(a,a+n);
            int x = n*p/10;
            printf("%s\n",s[a[x].name]);
        }
    }
}

1011 - Roundgod and Milk Tea

分析:依次给每个班级的学生喝奶。

优先喝班级内的学生还没有喝的班级的奶茶,不够了再喝班级内的学生已经喝过的班级的奶茶。

#include "bits/stdc++.h"

namespace fastIO {
#define BUF_SIZE 100000
    bool IOerror = 0;

    inline char nc() {
        static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
        if (p1 == pend) {
            p1 = buf;
            pend = buf + fread(buf, 1, BUF_SIZE, stdin);
            if (pend == p1) {
                IOerror = 1;
                return -1;
            }
        }
        return *p1++;
    }

    inline bool blank(char ch) { return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; }

    inline void read(int &x) {
        char ch;
        while (blank(ch = nc()));
        if (IOerror) return;
        //bool flag = 0;
        //if (ch == '-') {ch = nc();flag = 1; }
        for (x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
        //if (flag)x = -x;
    }

    inline void Out(int a) {
        if (a < 0) {
            putchar('-');
            a = -a;
        }
        if (a >= 10) {
            Out(a / 10);
        }
        putchar(a % 10 + '0');
    }

#undef BUF_SIZE
};
using namespace fastIO;



using namespace std;
#define LL long long
const int mod = 1e9 + 7;

long long qk(long long a, long long n) {
    long long res = 1;
    while (n) {
        if (n & 1)res = res * a % mod;
        n >>= 1;
        a = a * a % mod;
    }
    return res;
}

const int maxn = 1e6 + 5;
int a[maxn], b[maxn];

struct dd {
    int id, x;

    bool friend operator<(dd a, dd b) {
        return a.x < b.x;
    }
};

int main() {
    int t;
    read(t);
    while (t--) {
        int n;
        read(n);
        priority_queue<dd> q1;
        long long q2 = 0;
        for (int i = 0; i < n; i++) {
            read(a[i]);read(b[i]);
            q1.push({i, b[i]});
        }
        long long ans = 0;
        for (int i = 0; i < n; i++) {
            while (q1.size() && a[i]) {
                dd now = q1.top();
                q1.pop();
                if (now.id <= i)continue;
                else {
                    if (now.x > a[i]) {
                        now.x -= a[i];
                        b[now.id] = now.x;
                        q1.push(now);
                        ans += a[i];
                        a[i] = 0;
                    } else {
                        a[i] -= now.x;
                        ans += now.x;
                        b[now.id] = 0;
                    }
                }
            }
            if (q2 >= a[i]) {
                q2 -= a[i];
                ans += a[i];
                a[i] = 0;
            } else {
                ans += q2;
                q2 = 0;
                a[i] -= q2;
            }
            q2 += b[i];
        }
        printf("%lld\n", ans);
    }

    return 0;
}

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值